Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.
To
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}
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)