Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.
To
perl, no evals, 144 chars, works multiple times, supports multiple dice rolls
sub e{($c=pop)=~y/+* /PT/d;$b='(\d+)';map{$a=0while$c=~s!$b?$_$b!$d=$1||1;$a+=1+int rand$2for 1..$d;$e=$2;/d/?$a:/P/?$d+$e:$d*$e!e}qw(d T P);$c}
Expanded version, with comments
sub f {
($c = pop); #assign first function argument to $c
$c =~ tr/+* /PT/d; #replace + and * so we won't have to escape them later.
#also remove spaces
#for each of 'd','T' and 'P', assign to $_ and run the following
map {
#repeatedly replace in $c the first instance of with
#the result of the code in second part of regex, capturing both numbers and
#setting $a to zero after every iteration
$a=0 while $c =~ s[(\d+)?$_(\d+)][
$d = $1 || 1; #save first parameter (or 1 if not defined) as later regex
#will overwrite it
#roll $d dice, sum in $a
for (1..$d)
{
$a += 1 + int rand $2;
}
$e = $2; #save second parameter, following regexes will overwrite
#Code blocks return the value of their last statement
if (/d/)
{
$a; #calculated dice throw
}
elsif (/P/)
{
$d + $e;
}
else
{
$d * $e;
}
]e;
} qw(d T P);
return $c;
}
EDIT cleaned up, updated explanation to latest version