Rules
Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.
To clear the things up, here comes EBNF definition of legal expressions:
roll ::= [positive integer], "d", positive integer
entity ::= roll | positive number
expression ::= entity { [, whitespace], "+"|"*"[, whitespace], entity }
Example inputs:
- "3d6 + 12"
- "4*d12 + 3"
- "d100"
Using eval functions, or similar, is not forbidden, but I encourage to solving without using these. Re-entrancy is welcome.
I cannot provide test-cases, as output should be random ;).
Format your answers' titles: language, n characters (important notes — no eval, etc.)
My ruby solution, 92 81 characters, using eval:
def f s
eval s.gsub(/(\d+)?d(\d+)/i){eval"a+=rand $2.to_i;"*a=($1||1).to_i}
end
Another ruby solution, not shorter (92 characters), but I find it interesting — it still uses eval but this time in quite creative way.
class Fixnum
def**b
eval"a+=rand b;"*a=self
end
end
def f s
eval s.gsub(/d/,'**')
end
perl eval version, 72 chars
runs like
Based on the ruby solution, can only run once(you should
undef $a
between runs).shorter version, 68 chars, funky (0 based) dice
EDIT
perl 5.8.8 didn't like the previous version, here's a 73 char version that works
70 char version supporting multiple rolls
F# (no eval and no regex)
233 characters
This solution should be fully generic, in that it can handle just about any string you throw at it, even something crazy such as:
Need to define this globally:
Fully obfuscated version:
Readable version:
I'm challenging someone to beat this solution (in any language) without using
eval
or regular expressions. I think it's likely to be possible, but I am interested in seeing the approach still.