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.


1 rem 24 game
2 rem for rosetta code
10 rem use appropriate basic base address
11 bh=08:bl=01: rem $0801 commodore 64
12 rem bh=16:bl=01: rem $1001 commodore +4
13 rem bh=18:bl=01: rem $1201 commodore vic-20 (35k ram)
14 rem bh=04:bl=01: rem $0401 commodore pet
15 rem bh=28:bl=01: rem $1c01 commodore 128 (bank 0)
 
35 print chr$(147);chr$(14);"Initializing...":gosub 1400
40 n$="":x=rnd(-ti):rem similar to 'randomize'
45 for i=1 to 4
50 t$=str$(int(rnd(1)*9)+1)
55 n$=n$+mid$(t$,2,1)
60 next i
 
65 print chr$(147)
70 print spc(16);"24 Game"
71 print:print " The goal of this game is to formulate"
72 print:print " an arithmetic expression that"
73 print:print " evaluates to a value of 24, however"
74 print:print " you may use only the four numbers"
75 print:print " given at random by the computer and"
76 print:print " the standard arithmetic operations of"
77 print:print " add, subtract, multiply, and divide."
78 print:print " Each digit must be used by itself. "
79 print:print " (e.g. if given 1, 2, 3, 4, you cannot"
80 print:print " combine 1 and 2 to make 12.)"
89 gosub 1000
 
90 i$="":f$="":p$=""
95 print chr$(147);"Allowed characters:"
100 i$=n$+"+-*/()"
110 print
120 for i=1 to len(i$)
130 print mid$(i$,i,1);" ";
140 next i:print
150 print:print "Spaces are ignored."
155 print "Enter 'end' to end.":print
160 input "Enter the formula";f$
170 if f$="end" then print "Program terminated.":end 
 
180 print:print "Checking syntax... ";tab(34);
190 for i=1 to len(f$)
200 if mid$(f$,i,1)=" " then next i
210 c$=mid$(f$,i,1)
220 if c$="+" or c$="-" or c$="*" or c$="/" then p$=p$+"o":goto 250
230 if c$="(" or c$=")" then p$=p$+c$:goto 250
240 p$=p$+"n"
250 next i
260 restore
270 for i=1 to 11
280 read t$
290 if t$=p$ then i=11
300 next i
310 if t$<>p$ then gosub 1100:gosub 1000:goto 90
 
315 print "OK":print "Checking for illegal numbers... ";tab(34);
320 for i=1 to len(f$)
330 for j=1 to 10
335 ft$=mid$(f$,i,1)
336 il$=left$(i$,j-1):it$=mid$(i$,j,1):ir$=mid$(i$,j+1,len(i$))
340 if ft$=it$ and ft$>"0" and ft$<="9" then i$=il$+" "+ir$
350 next j
360 next i
370 if mid$(i$,1,4)<>"    " then gosub 1200:gosub 1000:goto 90
 
375 print "OK":print "Evaluating expression...":print:print tab(10);f$;" =";
380 gosub 600:rem r=val(f$)
390 print r;" "
400 if r<>24 then gosub 1300:gosub 1000:goto 90
410 print "Correct!"
 
420 print:print "Would you like to go again (y/n)? ";
425 get k$:if k$<>"y" and k$<>"n" then 425
430 print k$
435 if k$="y" then goto 40
440 print:print "Very well. Have a nice day!"
450 end
 
500 rem pattern matching
501 data "nononon","(non)onon","nono(non)"
504 data "no(no(non))","((non)on)on","no(non)on"
507 data "(non)o(non)","no((non)on)","(nonon)on"
510 data "(no(non))on","no(nonon)"
 
600 rem get basic to evaluate our expression
605 a$="r="+f$:gosub 1440
610 for i=1 to len(a$)
615 rem simple token translation
620 b=asc(mid$(a$,i,1))
625 if (b>41 and b<48) or b=61 or b=94 then b=t(b)
630 poke (ad+i-1),b
635 next
640 gosub 2000
645 rem gosub 1440:rem uncomment to clear evaluation line after use
650 return
 
1000 rem screen pause
1005 pt$=" Press a key to continue. "
1010 print:print spc(20-int(len(pt$)/2));
1015 print chr$(18);pt$;chr$(146);
1020 get k$:if k$=""then 1020
1030 return
 
1100 rem syntax error
1105 print "ERROR":print
1110 print "Maybe something is out of place..."
1120 return
 
1200 rem invalid arguments
1205 print "ERROR":print
1210 print "?Invalid Arguments - "
1215 print "You used a number that is not allowed."
1220 return
 
1300 rem wrong formula
1305 print:print "Wrong answer. Try again."
1310 return
 
1400 dim t(94):t(43)=170:t(45)=171:t(42)=172:t(47)=173:t(61)=178:t(94)=174
1405 rem locate line 2005 in ram
1410 lh=bh:ll=bl:nh=0:nl=0
1415 ad=lh*256+ll
1420 lh=peek(ad+1):ll=peek(ad)
1425 nl=peek(ad+2):nh=peek(ad+3):n=nh*256+nl
1430 if n<>2005 then goto 1415
1435 ad=ad+4:return
 
1440 for j=ad to ad+73:poke j,asc(":"):next
1445 return
 
2000 rem put 74 colons on the next line
2005 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2010 return
 