const digits = (1..9 -> pick(4))
const grammar = Regex(
'^ (?&exp) \z
(?(DEFINE)
(?<exp> ( (?&term) (?&op) (?&term) )+ )
(?<term> \( (?&exp) \) | [' + digits.join + '])
(?<op> [\-+*/] )
)', 'x'
)
say "Here are your digits: #{digits.join(' ')}"
loop {
var input = read("Expression: ", String)
var expr = input
expr -= /\s+/g
if (input == 'q') {
say "Goodbye. Sorry you couldn't win."
break
}
var given_digits = digits.map{.to_s}.sort.join
var entry_digits = input.scan(/\d/).sort.join
if ((given_digits != entry_digits) || (expr !~ grammar)) {
say "That's not valid"
next
}
given(var n = eval(input)) {
when (24) { say "You win!"; break }
default { say "Sorry, your expression is #{n}, not 24" }
}
}
Output:
Here are your digits: 8 2 3 4
Expression: 8 * (2 - (3 + 4))
Sorry, your expression is -40, not 24
Expression: 8 * (2 - (3 -
That's not valid
Expression: 8 * (2 - (3 - 4))
You win!