准备去死?


22

背景

桌上型角色扮演游戏中ennui的一种来源是处理涉及许多骰子的掷骰。施放解散咒语可能是瞬间的,但滚动并加在一起40个骰子肯定不是!

rpg.stackexchange.com上讨论了许多处理此问题的建议。但是,其中一些(例如使用滚轴程序或平均骰子)会剥夺玩家的一些乐趣和控制感。其他方法,例如滚动4个骰子并将总数乘以10,会使结果波动更大(平均骰子作用相反)。

这个问题涉及减少骰子掷骰数而不改变平均结果(均值)或其摆动(方差)的方法。

记数法和数学

在这个问题中,我们将使用以下表示法来表示骰子掷骰:

  • n d k(例如40d6)是指k面模具的n卷总和。
  • 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( d ķ * 一个 + Ñ d * b + c ^ ] = 一个。² 中号 .VAR(1D ķ)+ b ²。Ñ .VAR(1D

任务

给定三个整数nkr,您的程序最多应输出一种在最多r个滚动中近似n d k的方式,并具有以下约束:

  • 解应具有与n d k相同的均值和方差。
  • 该解决方案应包含最大数量的小于或等于r的卷,因为更多的卷会产生更平滑的分布。
  • 您应该将解决方案限制为仅使用k边骰子,除非您的目标是奖金(请参阅下文)。
  • 如果没有解决方案(因为r太小),则程序应输出字符串“ I AM A SEXY SHOELESS GOD OF WAR!”。
  • 参数以单个用空格分隔的字符串形式传入。
  • 你可以假设1≤ Ñ ≤100,1≤ [RÑķ是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参考。;)(嗯,因为实际上这是一个非常好的挑战。)
Martin Ender 2015年

1
也许使用我们新的$ \ LaTeX $功能来解决这个问题?
orlp 2015年

2
@UriZarfaty:我更新了您的公式以使用LaTeX。希望没事。如果您不喜欢它,则可以回滚该帖子,并将其恢复为以前的样子。
Alex A.

1
我已经回滚了LaTeX编辑,因为不幸的是,现在它会再次被停用
马丁·恩德

1
#SadPanda-我认为这将是对“ Hello。我的名字叫Inigo Montoya。您杀死了我的父亲。准备去世。”的代码挑战。
scunliffe

Answers:


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\{.*+}/^=},找到乘法因子ab等; 并^@{-}/@)*.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的事实,并且在规范中有两个半漏洞(哎呀!):无需禁止打印冗余格式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!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.