#!/usr/bin/ruby

#
## https://rosettacode.org/wiki/24_game
#

const digits  = @(1..9).shuffle.first(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 = Sys.scanln("Expression: ");
 
    var expr = input;
    expr -= /\s+/g;    # remove all whitespace
 
    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" }
    }
}