The 24 Game tests one's mental arithmetic.



Task
Write a program that randomly chooses and displays four digits, each from 1 ──► 9 (inclusive) with repetitions allowed.

The program should prompt for the player to enter an arithmetic expression using just those, and all of those four digits, used exactly once each. The program should check then evaluate the expression.

The goal is for the player to enter an expression that (numerically) evaluates to 24.

 Only the following operators/functions are allowed: multiplication, division, addition, subtraction
 Division should use floating point or rational arithmetic, etc, to preserve remainders.
 Brackets are allowed, if using an infix expression evaluator.
 Forming multiple digit numbers from the supplied digits is disallowed. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).
 The order of the digits when given does not have to be preserved.


Notes
 The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
 The task is not for the program to generate the expression, or test whether an expression is even possible.


Related tasks
 24 game/Solve


Reference
 The 24 Game on h2g2.


dim d(4)
dim chk(4)
print "The 24 Game"
print
print "Given four digits and using just the +, -, *, and / operators; and the"
print "possible use of brackets, (), enter an expression that equates to 24."
 
do
    d$=""
    for i = 1 to 4
        d(i)=int(rnd(1)*9)+1    '1..9
        chk(i)=d(i)
        d$=d$;d(i)  'valid digits, to check with Instr
    next
 
    print
    print "These are your four digits: ";
    for i = 1 to 4
        print d(i);left$(",",i<>4);
    next
    print
 
    Print "Enter expression:"
    Input "24 = ";expr$
    'check expr$ for validity
 
    'check right digits used
    failed = 0
    for i = 1 to len(expr$)
        c$=mid$(expr$,i,1)
        if instr("123456789", c$)<>0 then 'digit
            if instr(d$, c$)=0 then failed = 1: exit for
            if i>1 and instr("123456789", mid$(expr$,i-1,1))<>0 then failed = 2: exit for
            for j =1 to 4
                if chk(j)=val(c$) then chk(j)=0: exit for
            next
        end if
    next
    if failed=1 then
        print "Wrong digit (";c$;")"
        goto [fail]
    end if
 
    if failed=2 then
        print "Multiple digit numbers is disallowed."
        goto [fail]
    end if
 
    'check all digits used
    if chk(1)+ chk(2)+ chk(3)+ chk(4)<>0 then
        print "Not all digits used"
        goto [fail]
    end if
 
    'check valid operations
    failed = 0
    for i = 1 to len(expr$)
        c$=mid$(expr$,i,1)
        if instr("+-*/()"+d$, c$)=0 then failed = 1: exit for
    next
    if failed then
        print "Wrong operation (";c$;")"
        goto [fail]
    end if
    'some errors (like brackets) trapped by error handler
    Err$=""
    res=evalWithErrCheck(expr$)
    if Err$<>"" then
        print "Error in expression"
        goto [fail]
    end if
    if res = 24 then
        print "Correct!"
    else
        print "Wrong! (you got ";res ;")"
    end if
[fail]
    Input "Play again (y/n)? "; ans$
loop while ans$="y"
end
 
function evalWithErrCheck(expr$)
    on error goto [handler]
    evalWithErrCheck=eval(expr$)
    exit function
[handler]
end function