Готуйтеся… померти?


22

Фон

Одним із джерел приємностей у настільних рольових іграх є робота з рулонами, в яких задіяно багато кісток. Заклинання заклинання про дезінтеграцію може бути миттєвим, але згортання та додавання 40 кубиків точно не є!

Ряд пропозицій щодо вирішення цього питання обговорюється на rpg.stackexchange.com . Однак деякі з них, наприклад, користуючись роликовою програмою або усереднюючи кістки, відбирають у гравців частину задоволення та почуття контролю. Інші, такі як розкачування 4-х кубиків та множення загальної кількості на 10, роблять результати набагато хиткішими (тоді як усереднення кісток діє у зворотному напрямку).

Це питання стосується способу зменшення кількості рулонів кісток, не змінюючи ні середнього результату (середнього), ні його розмахування (дисперсії).

Позначення та математика

У цьому запиті ми будемо використовувати наступні позначення для представлення рулонів з кістки:

  • n d k (наприклад, 40d6) відноситься до суми n рулонів k-однобічного штампу.
  • n d k * c (наприклад, 4d6 * 10) описує множення результату на постійну c.
  • Можна також додати рулони (наприклад, 4d6 * 10 + 40d6) та константи (наприклад, 4d6 + 10).

Для одного ролика матриці ми можемо показати, що:

  • Середнє значення : E [1d k ] = (k + 1) / 2
  • Варіант : Var (1d k ) = (k-1) (k + 1) / 12

Використовуючи основні властивості середнього та відхилення, ми можемо також зробити висновок про те, що:

  • Середнє значення : E [ m d k * a + n d l * b + c ] = am .E [1d k ] + bn . [1d l ] + c
  • Різниця : вар ( м д до * + п д л * Ь + с ] = . ² м .var (1d до ) + б ². П .var (1d л )

Завдання

Враховуючи три цілих числа n , k і r , ваша програма повинна вивести спосіб наближення n d k у максимум r- рулонах із наступними обмеженнями:

  • Розв’язок повинен мати те саме середнє значення та дисперсію, що й n d k .
  • Розчин повинен містити якомога більшу кількість рулонів, меншу або рівну r , оскільки більше рулонів забезпечує більш плавне розподіл.
  • Ви повинні обмежувати свої рішення лише використанням k- однобічних кубиків, якщо ви не прагнете отримати бонус (див. Нижче).
  • Якщо рішення немає (оскільки r занадто мало), програма повинна вивести рядок "Я - ШЕКСИЙ БЕЗПЕЧНИЙ БОГ ВІЙНИ!".
  • Параметри передаються у вигляді єдиного рядка, розділеного пробілом.
  • Ви можете припустити, що 1 ≤ n ≤ 100, 1 ≤ rn і що k - один із 4, 6, 8, 10, 12 і 20 (стандартні кістки, які використовуються на стільницях).
  • Вихід повинен бути у форматі, описаному в нотації (наприклад, 4d6 * 10 + 5), з необов’язковими пробілами навколо + s, але ніде більше. Одиничні множники також необов’язкові: і 4d6 * 1, і 4d6 є дійсними.

Ви можете написати програму або функцію, взявши вхід через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції. Результати слід надрукувати в STDOUT (або найближчу альтернативу) або повернути у вигляді рядка.

Приклади

>> "10 6 10"
10d6
>> "10 6 4"
2d6*2+2d6+14
>> "10 6 3"
1d6*3+1d6+21
>> "10 6 2"
1d6*3+1d6+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!

Оцінка балів

Найкоротший код виграє. Діють стандартні правила.

Бонус

-33% (округлюється до віднімання), якщо ваша програма також повертає рішення, які включають дійсні кістки, крім k (де дійсні значення, як згадувалося вище, 4, 6, 8, 10, 12 і 20). Якщо ви вирішили це зробити, то завжди слід повертати такі рішення, коли це доречно, і обробляти рішення, які використовують кілька типів штампу. Приклад:

>> "7 4 3"
3d6+7

6
+1 Для посилання на OotS. ;) (Ну і тому, що це насправді приємний виклик.)
Мартін Ендер

1
Можливо, використовуйте наші нові $ \ LaTeX $ можливості для вирішення цього питання?
orlp

2
@UriZarfaty: Я оновив ваші формули для використання LaTeX. Сподіваюсь, це все добре. Якщо вам це не подобається, ви можете просто відкатати публікацію, і вона повернеться до того, як це було раніше.
Олексій А.

1
Я відмовив редагування LaTeX, тому що, на жаль, він буде відключений знову .
Мартін Ендер

1
#SadPanda - Я думав, що це буде посиланням на кодове завдання "Привіт. Мене звуть Ініго Монтоя. Ти вбив мого батька. Готуйся померти".
сканліфф

Відповіді:


5

GolfScript ( 163 143 133 байт)

~@:^\?,{^base 0-}%{0\{.*+}/^=},.{{,}$-1=..&{[[1$[1$]/,(3$@]'d*+'1/]zip}%^@{-}/@)*.2/\1&'.5'*}{];'I AM A SEXY SHOELESS GOD OF WAR!'}if

Демонстрація в Інтернеті

Якщо не змішувати типи кубиків, проблема зводиться до вираження nу вигляді суми не більше rквадратів і kне має значення, за винятком обчислення константи в кінці. Основна частина цієї відповіді є бухоблік потрібно , щоб висловити результат у бажаному форматі: фактичний розрахунок , ^\?,{^base}%{0\{.*+}/^=},щоб знайти чинники множення a, bі т.д.; і ^@{-}/@)*.2/обчислити константу.

Розсічення

~                # Stack: n k r
@:^\?,{          # Store n in ^, and for 0 to n**r
  ^base 0-       #   convert to base n and remove 0s.
}%               # Stack: k [arrays of up to r values from 1 to n-1]
{0\{.*+}/^=},    # Filter them to arrays whose sum of squares is n,
                 #   i.e. to multipliers which have the right variance
.{               # If any multiplier array passes the filter...
  {,}$-1=        #   Pick one with the greater number of rolls
                 #   Stack: k [multipliers]
  ..&{           #   Map each distinct multiplier a...
    [[           #     Gather in nested array for later zip
      1$[1$]/,(  #       Split a copy of the multipliers around a to count the as
                 #       Let's denote that count as m
                 #       Stack: k [multipliers] a [ [ m
      3$@        #       Copy k and rotate the a inside the nested array
     ]           #       Stack: k [multipliers] [ [m k a]
      'd*+'1/    #       Push an array ['d' '*' '+'] and close nested array
    ]zip         #       Giving [[m 'd'] [k '*'] [a '+']]
                 #       which will be printed as mdk*a+
  }%             #   Stack: k [multipliers] [string representations of dice]
  ^@{-}/@)*      #   Compute (n - sum(multipliers)) * (k + 1)
                 #   That's twice the constant we need to add to fix the mean
  .2/\1&'.5'*    #   And convert it to a renderable form, including .5 if needed
}{               # Otherwise clear the stack and push the error message
  ];'I AM A SEXY SHOELESS GOD OF WAR!'
}if

1

Пітон, 487 461 452 - 33% = 303 байт

Оскільки ніхто інший цього не робив, ось рішення, яке обробляє різні типи кісток. Як і інше рішення, воно генерує низку можливих рішень і фільтрує їх. Він використовує той факт, що (k + 1) (k-1) = k ^ 2-1 та дві напівпробої в специфікації (oops!): Відсутність заборони на друк надлишкової форми 0d k * a (що економить всі 5 байтів!) і відсутність обмеження часу роботи (воно стає повільним досить швидко, хоча і запускає всі наведені приклади).

from itertools import*
N,K,R=map(int,input().split())
S=lambda l:sum([x[0]for x in l])
s=[x for x in product(*[[(n,k,a)for n in range(N*(K**2-1)/((k**2-1)*a**2)+1)]for a in range(1,N+1)for k in[4,6,8,10,12,20]if a**2<=N])if sum([n*(k**2-1)*a**2 for n,k,a in x])==N*K**2-N and S(x)<=R]
if s:s=max(s,key=S);print"+".join(["%sd%s*%s"%x for x in s]+[str(int(N*(K+1)/2.-sum([n*a*(k+1)/2.for n,k,a in s])))])
else:print"I AM A SEXY SHOELESS GOD OF WAR!"

Для кращого результату додайте if x[0]після "%sd%s*%s"%x for x in s:

>> "7 4 3"
3d6+7
>> "10 6 3"
1d6*1+1d8*1+1d8*2+18
>> "10 6 2"
1d6*1+1d6*3+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.