python、隠蔽バージョンで 197 文字。
読み取り可能なバージョン: 369 文字。評価なし、単純な解析。
import random
def dice(s):
return sum(term(x) for x in s.split('+'))
def term(t):
p = t.split('*')
return factor(p[0]) if len(p)==1 else factor(p[0])*factor(p[1])
def factor(f):
p = f.split('d')
if len(p)==1:
return int(f)
return sum(random.randint(1, int(g[1]) if g[1] else 6) for \
i in range(int(g[0]) if g[0] else 1))
圧縮バージョン: 258 文字、1 文字の名前、乱用された条件式、論理式のショートカット:
import random
def d(s):
return sum(t(x.split('*')) for x in s.split('+'))
def t(p):
return f(p[0])*f(p[1]) if p[1:] else f(p[0])
def f(s):
g = s.split('d')
return sum(random.randint(1, int(g[1] or 6)) for i in range(int(g[0] or 1))) if g[1:] else int(s)
隠蔽されたバージョン: 216 文字、reduce を使用し、「def」、「return」を避けるために重くマップします。
import random
def d(s):
return sum(map(lambda t:reduce(lambda x,y:x*y,map(lambda f:reduce(lambda x,y:sum(random.randint(1,int(y or 6)) for i in range(int(x or 1))), f.split('d')+[1]),t.split('*')),1),s.split('+')))
最終バージョン: 197 文字、@Brain のコメントで折りたたまれ、テスト実行が追加されました。
import random
R=reduce;D=lambda s:sum(map(lambda t:R(int.__mul__,map(lambda f:R(lambda x,y:sum(random.randint(1,int(y or 6))for i in[0]*int(x or 1)),f.split('d')+[1]),t.split('*'))),s.split('+')))
テスト:
>>> for dice_expr in ["3d6 + 12", "4*d12 + 3","3d+12", "43d29d16d21*9+d7d9*91+2*d24*7"]: print dice_expr, ": ", list(D(dice_expr) for i in range(10))
...
3d6 + 12 : [22, 21, 22, 27, 21, 22, 25, 19, 22, 25]
4*d12 + 3 : [7, 39, 23, 35, 23, 23, 35, 27, 23, 7]
3d+12 : [16, 25, 21, 25, 20, 18, 27, 18, 27, 25]
43d29d16d21*9+d7d9*91+2*d24*7 : [571338, 550124, 539370, 578099, 496948, 525259, 527563, 546459, 615556, 588495]
このソリューションは、隣接する数字のない空白を処理できません。したがって、「43d29d16d21*9+d7d9*91+2*d24*7」は機能しますが、「43d29d16d21*9 + d7d9*91 + 2*d24*7」は機能しません。2 番目のスペース (「+」と「」の間) のためです。 d")。最初に s から空白を削除することで修正できますが、これによりコードが 200 文字を超えてしまうため、バグはそのままにしておきます。