Evaluate dice rolling notation strings

前端 未结 14 1426
甜味超标
甜味超标 2021-01-30 14:55

Rules

Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.

To

相关标签:
14条回答
  • 2021-01-30 15:35

    perl eval version, 72 chars

    sub e{$_=pop;s/(\d+)?d(\d+)/\$a/i;$a+=1+int rand$2-1for 0...$1-1;eval$_}
    

    runs like

    print e("4*d12+3"),"\n";
    

    Based on the ruby solution, can only run once(you should undef $a between runs).

    shorter version, 68 chars, funky (0 based) dice

    sub e{$_=pop;s/(\d+)?d(\d+)/\$a/i;$a+=int rand$2for 0...$1-1;eval$_}
    

    EDIT

    perl 5.8.8 didn't like the previous version, here's a 73 char version that works

    sub e{$_=pop;s/(\d+)?d(\d+)/\$a/i;$a+=1+int rand$2-1for 1...$1||1;eval$_}
    

    70 char version supporting multiple rolls

    sub e{$_=pop;s/(\d*)d(\d+)/$a=$1||1;$a+=int rand$a*$2-($a-1)/ieg;eval}
    
    0 讨论(0)
  • 2021-01-30 15:35

    Python 124 chars with eval, 154 without.

    Just to show python doesn't have to be readable, here's a 124 character solution, with a similar eval-based approach to the original:

    import random,re
    f=lambda s:eval(re.sub(r'(\d*)d(\d+)',lambda m:int(m.group(1)or 1)*('+random.randint(1,%s)'%m.group(2)),s))
    

    [Edit] And here's a 154 character one without eval:

    import random,re
    f=lambda s:sum(int(c or 0)+sum(random.randint(1,int(b))for i in[0]*int(a or 1))for a,b,c in re.findall(r'(\d*)d(\d+)(\s*[+-]\s*\d+)?',s))
    

    Note: both will work for inputs like "2d6 + 1d3 + 5" but don't support more advanced variants like "2d3d6" or negative dice ("1d6-4" is OK, but "1d6-2d4" isn't) (You can shave off 2 characters to not support negative numbers at all in the second one instead)

    0 讨论(0)
提交回复
热议问题