24 game: Difference between revisions

32,694 bytes added ,  1 month ago
m
(Added 11l)
(37 intermediate revisions by 19 users not shown)
Line 36:
{{trans|C++}}
 
<langsyntaxhighlight lang=11l>T Error
String message
F (message)
Line 47:
F op(f)
I .stk.len < 2
X.throw Error(‘Improperly written expression’)
V b = .stk.pop()
V a = .stk.pop()
Line 62:
E I c == ‘/’ {.op((a, b) -> a / b)}
E I c != ‘ ’
X.throw Error(‘Wrong char: ’c)
 
F get_result()
I .stk.len != 1
X.throw Error(‘Improperly written expression’)
R .stk.last
 
Line 94:
 
X.catch Error error
print(‘Error: ’error.message)</langsyntaxhighlight>
 
{{out}}
Line 101:
=={{header|8th}}==
This is a fully-worked sample of the game in 8th, showing error-detection and user-restriction techniques:
<langsyntaxhighlight lang=forth>
\ Generate four random digits and display to the user
\ then get an expression from the user using +, -, / and * and the digits
Line 211:
start
</syntaxhighlight>
</lang>
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<langsyntaxhighlight lang=AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program game24_64.s */
Line 701:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
=={{header|ABAP}}==
See [[24 game/ABAP]]
Line 707:
=={{header|Ada}}==
game24.adb:
<langsyntaxhighlight lang=Ada>with Ada.Float_Text_IO;
with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
Line 878:
end if;
end;
end Game_24;</langsyntaxhighlight>
 
{{out}}
Line 897:
You won!
Enter N for a new game, or try another solution.</pre>
 
=={{header|ALGOL 68}}==
Uses infix expressions.
<syntaxhighlight lang="algol68">
BEGIN # play the 24 game - present the user with 4 digits and invite them to #
# enter an expression using the digits that evaluates to 24 #
 
[ 0 : 9 ]INT expression digits; # the digits entered by the user #
[ 0 : 9 ]INT puzzle digits; # the digits for the puzzle #
PROC eval = ( STRING expr )REAL: # parses and evaluates expr #
BEGIN
# syntax: expression = term ( ( "+" | "-" ) term )* #
# term = factor ( ( "*" | "/" ) factor ) * #
# factor = "0" | "1" | "2" | ... | "9" #
# | "(" expression ")" #
INT x pos := LWB expr - 1;
INT x end := UPB expr;
BOOL ok := TRUE;
PROC error = ( STRING msg )VOID:
IF ok THEN # this is the firstt error #
ok := FALSE;
print( ( msg, newline ) );
x pos := x end + 1
FI # error # ;
PROC curr ch = CHAR: IF x pos > x end THEN REPR 0 ELSE expr[ x pos ] FI;
PROC next ch = VOID: WHILE x pos +:= 1; curr ch = " " DO SKIP OD;
PROC factor = REAL:
IF curr ch >= "0" AND curr ch <= "9" THEN
INT digit = ABS curr ch - ABS "0";
REAL result = digit;
expression digits[ digit ] +:= 1;
next ch;
result
ELIF curr ch = "(" THEN
next ch;
REAL result = expression;
IF curr ch = ")" THEN
next ch
ELSE
error( """)"" expected after sub-expression" )
FI;
result
ELSE
error( "Unexpected """ + curr ch + """" );
0
FI # factor # ;
PROC term = REAL:
BEGIN
REAL result := factor;
WHILE curr ch = "*" OR curr ch = "/" DO
CHAR op = curr ch;
next ch;
IF op = "*" THEN result *:= factor ELSE result /:= factor FI
OD;
result
END # term # ;
PROC expression = REAL:
BEGIN
REAL result := term;
WHILE curr ch = "+" OR curr ch = "-" DO
CHAR op = curr ch;
next ch;
IF op = "+" THEN result +:= term ELSE result -:= term FI
OD;
result
END # expression # ;
 
next ch;
IF curr ch = REPR 0 THEN
error( "Missing expression" );
0
ELSE
REAL result = expression;
IF curr ch /= REPR 0 THEN
error( "Unexpected text: """ + expr[ x pos : ] + """ after expression" )
FI;
result
FI
END # eval # ;
 
WHILE
FOR i FROM 0 TO 9 DO # initialise the digit counts #
expression digits[ i ] := 0;
puzzle digits[ i ] := 0
OD;
print( ( "Enter an expression using these digits:" ) );
FOR i TO 4 DO # pick 4 random digits #
INT digit := 1 + ENTIER ( next random * 9 );
IF digit > 9 THEN digit := 9 FI;
puzzle digits[ digit ] +:= 1;
print( ( whole( digit, - 2 ) ) )
OD;
print( ( " that evaluates to 24: " ) );
# get and check the expression #
STRING expr;
read( ( expr, newline ) );
REAL result = eval( expr );
BOOL same := TRUE;
FOR i FROM 0 TO 9 WHILE same := puzzle digits[ i ] = expression digits[ i ] DO SKIP OD;
IF NOT same THEN
print( ( "That expression didn't contain the puzzle digits", newline ) )
ELIF result = 24 THEN
print( ( "Yes! That expression evaluates to 24", newline ) )
ELSE
print( ( "No - that expression evaluates to ", fixed( result, -8, 4 ), newline ) )
FI;
print( ( newline, "Play again [y/n]? " ) );
STRING play again;
read( ( play again, newline ) );
play again = "y" OR play again = "Y" OR play again = ""
DO SKIP OD
 
END
</syntaxhighlight>
{{out}}
<pre>
Enter an expression using these digits: 2 5 3 5 that evaluates to 24: (3+5)*(5-2)
Yes! That expression evaluates to 24
 
Play again [y/n]?
Enter an expression using these digits: 8 8 6 6 that evaluates to 24: 8+6+8/6
No - that expression evaluates to 15.3333
 
Play again [y/n]?
Enter an expression using these digits: 2 1 5 1 that evaluates to 24: (1+1)*(7+5)
That expression didn't contain the puzzle digits
 
Play again [y/n]? n
</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<langsyntaxhighlight lang=APL>tfgame←{⎕IO←1
⎕←d←?⍵⍴9
i←⍞
Line 907 ⟶ 1,036:
24≠⍎i:'nope'
'Yeah!'
}</langsyntaxhighlight>
{{out}}
<pre> tfgame 4
Line 919 ⟶ 1,048:
nope
</pre>
 
=={{header|Applesoft BASIC}}==
 
This was taken from both the [[#Commodore_BASIC|Commodore BASIC]] and [[#ZX_Spectrum_Basic|ZX Spectrum Basic]] solutions.
 
<syntaxhighlight lang=ApplesoftBasic> 0 BH = PEEK (104):BL = PEEK (103)
1 GOSUB 1200: CALL - 868
10 LET N$ = ""
20 R = RND ( - ( PEEK (78) + PEEK (79) * 256)): REM RANDOMIZE
30 FOR I = 1 TO 4
40 LET N$ = N$ + STR$ ( INT ( RND (1) * 9) + 1)
50 NEXT I
60 PRINT " PRESS A KEY TO CONTINUE. ";: GET A$
65 LET I$ = "": LET F$ = "": LET P$ = ""
70 HOME
80 PRINT M$M$ SPC( 16)"24 GAME"
90 PRINT M$"ALLOWED CHARACTERS:"M$
100 LET I$ = N$ + "+-*/()"
110 HTAB 20
120 FOR I = 1 TO 10
130 PRINT MID$ (I$,I,1)" ";
140 NEXT I
150 PRINT M$ TAB( 7)"0 TO END"M$
160 INPUT "ENTER THE FORMULA: ";F$
170 IF F$ = "0" THEN END : GOTO 65
180 PRINT M$ TAB( 7)F$" = ";
190 FOR I = 1 TO LEN (F$)
200 LET C$ = MID$ (F$,I,1)
210 IF C$ = " " THEN LET F$ = MID$ (F$,1,I - 1) + MID$ (F$,I + 1): GOTO 250
220 IF C$ = "+" OR C$ = "-" OR C$ = "*" OR C$ = "/" THEN LET P$ = P$ + "O": GOTO 250
230 IF C$ = "(" OR C$ = ")" THEN LET P$ = P$ + C$: GOTO 250
240 LET P$ = P$ + "N"
250 NEXT I
260 RESTORE
270 FOR I = 1 TO 11
280 READ T$
290 IF T$ = P$ THEN LET I = 11
300 NEXT I
310 IF T$ < > P$ THEN INVERSE : PRINT "BAD CONSTRUCTION!"G$M$: NORMAL : GOTO 60
320 FOR I = 1 TO LEN (F$)
330 FOR J = 1 TO 10
340 IF ( MID$ (F$,I,1) = MID$ (I$,J,1)) AND MID$ (F$,I,1) > "0" AND MID$ (F$,I,1) < = "9" THEN LET I$ = MID$ (I$,1,J - 1) + " " + MID$ (I$,J + 1, LEN (I$))
350 NEXT J,I
370 IF MID$ (I$,1,4) < > " " THEN INVERSE : PRINT "INVALID ARGUMENTS!"G$M$: NORMAL : GOTO 60
380 GOSUB 600: REM LET R = VAL(F$)
390 PRINT R" ";
400 IF R < > 24 THEN INVERSE : PRINT "WRONG!"G$M$: NORMAL : GOTO 60
410 INVERSE : PRINT "CORRECT!"M$: NORMAL : GOTO 10
420 DATA"NONONON"
430 DATA"(NON)ONON"
440 DATA"NONO(NON)"
450 DATA"NO(NO(NON))"
460 DATA"((NON)ON)ON"
470 DATA"NO(NON)ON"
480 DATA"(NON)O(NON)"
485 DATA"NO((NON)ON)"
490 DATA"(NONON)ON"
495 DATA"(NO(NON))ON"
500 DATA"NO(NONON)"
600 REMGET BASIC TO EVALUATE OUR EXPRESSION
605 A$ = "R=" + F$: GOSUB 1440
610 FOR I = 1 TO LEN (A$)
615 REMSIMPLE 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
1200 M$ = CHR$ (13)
1210 G$ = CHR$ (7)
1220 HOME
1230 PRINT SPC( 16)"24 GAME"
1240 PRINT M$" THE GOAL OF THIS GAME IS TO FORMULATE"
1250 PRINT M$" AN ARITHMETIC EXPRESSION THAT"
1260 PRINT M$" EVALUATES TO A VALUE OF 24, HOWEVER"
1270 PRINT M$" YOU MAY USE ONLY THE FOUR NUMBERS"
1280 PRINT M$" GIVEN AT RANDOM BY THE COMPUTER AND"
1290 PRINT M$" THE STANDARD ARITHMETIC OPERATIONS OF"
1300 PRINT M$" ADD, SUBTRACT, MULTIPLY, AND DIVIDE."
1310 PRINT M$" EACH DIGIT MUST BE USED BY ITSELF. "
1320 PRINT M$" (E.G. IF GIVEN 1, 2, 3, 4, YOU CANNOT"
1330 PRINT M$" COMBINE 1 AND 2 TO MAKE 12.)"
1340 PRINT M$
1350 PRINT "INITIALIZING...";
1360 HTAB 1
1400 DIM T(94)
1401 T( ASC ("+")) = 200: REM $C8
1402 T( ASC ("-")) = 201: REM $C9
1403 T( ASC ("*")) = 202: REM $CA
1404 T( ASC ("/")) = 203: REM $CB
1405 T( ASC ("=")) = 208: REM $D0
1406 T( ASC ("^")) = 204: REM $CC
1409 REMLOCATE 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 + 12: POKE J, ASC (":"): NEXT
1445 RETURN
2000 REMPUT 13 COLONS ON THE NEXT LINE
2005 :::::::::::::
2010 RETURN
</syntaxhighlight>
 
=={{header|Argile}}==
{{works with|Argile|1.0.0}}
<langsyntaxhighlight lang=Argile>use std, array, list
 
do
Line 1,032 ⟶ 1,268:
error "unclosed parenthesis"
return x
</syntaxhighlight>
</lang>
compile with:
arc 24_game.arg -o 24_game.c && gcc 24_game.c -o 24_game /usr/lib/libargrt.a
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<langsyntaxhighlight lang=ARM Assembly>
/* ARM assembly Raspberry PI */
/* program game24.s */
Line 1,491 ⟶ 1,727:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
<pre>
24 Game
Line 1,511 ⟶ 1,747:
 
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang=rebol>print "-----------------------------"
print " Welcome to 24 Game"
print "-----------------------------"
 
digs: map 1..4 'x -> random 1 9
 
print ["The numbers you can use are:" join.with:" " digs]
 
print ""
 
validExpression?: function [expr][
loop expr 'item [
if or? inline? item block? item [
if not? validExpression? item -> return false
]
if symbol? item [
if not? contains? [+ / - *] item -> return false
]
if integer? item [
if not? contains? digs item -> return false
]
]
return true
]
 
result: 0
 
while [result<>24][
got: input "Enter an expression to form 24: "
blo: to :block got
if? validExpression? blo [
result: do blo
print ["The result is:" result]
]
else [
print "Invalid expression. Please try again!"
]
print ""
]
 
print "Well done!"</syntaxhighlight>
 
{{out}}
 
<pre>-----------------------------
Welcome to 24 Game
-----------------------------
The numbers you can use are: 3 2 2 1
 
Enter an expression to form 24: 3+2+2+1\
Invalid expression. Please try again!
 
Enter an expression to form 24: 3+2+2+1
The result is: 8
 
Enter an expression to form 24: (3+3+3+3+3)+2+2+1+1
The result is: 21
 
Enter an expression to form 24: (3+3+3+3+3)+2+2+1+1+1
The result is: 22
 
Enter an expression to form 24: 3+3+3+3+3+2+2+2+2+1+1
The result is: 25
 
Enter an expression to form 24: 3+3+3+3+3+2+2+2+2+1
The result is: 24
 
Well done!</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight lang=autohotkey>AutoExecute:
Title := "24 Game"
Gui, -MinimizeBox
Line 1,619 ⟶ 1,927:
FileDelete, %File%
Return, Result
}</langsyntaxhighlight>
 
=={{header|AutoIt}}==
<langsyntaxhighlight lang=AutoIt>
;AutoIt Script Example
;by Daniel Barnes
Line 1,697 ⟶ 2,005:
endif
EndFunc
</syntaxhighlight>
</lang>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang=bbcbasic> REM Choose four random digits (1-9) with repetitions allowed:
DIM digits%(4), check%(4)
FOR choice% = 1 TO 4
Line 1,765 ⟶ 2,073:
INPUT '"Play again", answer$
IF LEFT$(answer$,1) = "y" OR LEFT$(answer$,1) = "Y" THEN CLS : RUN
QUIT</langsyntaxhighlight>
 
=={{header|Befunge}}==
<langsyntaxhighlight lang=befunge>v > > >> v
2 2 1234
4 ^1?3^4
Line 1,793 ⟶ 2,101:
| -*84gg01g00<p00*84<v <
>00g:1+00p66*`#^_ "niW">:#,_@
</syntaxhighlight>
</lang>
The code functions by placing the 4 randomly generated numbers into the points labelled 1,2,3,4. In order to play, press the corresponding label to draw that number onto the stack, then press the corresponding operation (+,-,*,/) to perform it on the stack elements postfix-wise according to the rules of befunge (i.e. pop the values operate and push the answer back to the stack). When you wish to check your answer enter "=" and it will perform the checks to ensure that you haven't performed any illegal operations, that you have used all four numbers and that your final value is 24.
 
Line 1,810 ⟶ 2,118:
=={{header|Bracmat}}==
 
<langsyntaxhighlight lang=Bracmat> ( 24-game
= m-w m-z 4numbers answer expr numbers
, seed get-random convertBinaryMinusToUnary
Line 1,887 ⟶ 2,195:
)
& 24-game$(13.14)
& ;</langsyntaxhighlight>
<pre>Enter an expression that evaluates to 24 by combining the following numbers.
You may only use the operators + - * /
Line 1,934 ⟶ 2,242:
=={{header|C}}==
Simple recursive descent parser. It doesn't have a real lexer, because all tokens are single character (digits, operators and parens). Code is a little too long.
<langsyntaxhighlight lang=C>#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
Line 2,214 ⟶ 2,522:
}
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Available digits are: 5 2 3 9. Type an expression and I'll check it for you, or make new numbers.
Line 2,236 ⟶ 2,544:
See [[24 game/C]]
 
=={{header|C sharp|C#}}==
See [[24 game/CSharp]]
 
Line 2,244 ⟶ 2,552:
This uses the C++11 standard to simplify several parts of the code. Input is given in RPN format.
 
<langsyntaxhighlight lang=cpp>#include <random>
#include <iostream>
#include <stack>
Line 2,341 ⟶ 2,649:
}
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 2,358 ⟶ 2,666:
=={{header|Ceylon}}==
Be sure to import ceylon.random in you ceylon.module file.
<langsyntaxhighlight lang=ceylon>import ceylon.random {
DefaultRandom
}
Line 2,594 ⟶ 2,902:
}
}
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang=Clojure>
(ns rosettacode.24game)
 
Line 2,625 ⟶ 2,933:
; * checks prefix form, then checks to see that the numbers used
; and the numbers generated by the game are the same.
</syntaxhighlight>
</lang>
 
=={{header|COBOL}}==
<langsyntaxhighlight lang=COBOL> >>SOURCE FORMAT FREE
*> This code is dedicated to the public domain
*> This is GNUCobol 2.0
Line 3,471 ⟶ 3,779:
.
end program twentyfour.
</syntaxhighlight>
</lang>
 
=={{header|CoffeeScript}}==
{{works with|node.js}}
<langsyntaxhighlight lang=coffeescript>tty = require 'tty'
tty.setRawMode true
 
Line 3,528 ⟶ 3,836:
# begin taking input
process.stdin.resume()
</syntaxhighlight>
</lang>
 
=={{header|Commodore BASIC}}==
 
This solution was taken from the ZX Spectrum example further down, however, BASIC on the Spectrum features slightly different string handling functions. Most importantly, while the <code>val()</code> function on the Spectrum is able to parse complete mathematical expressions withwithin in athe string whileas convertingit converts it to a number, Commodore BASIC will only obtain only a single number provided that the first character is a valid numeric character and up to any non-numeric character. (Even floating-point numbers where 0 < n < 1 must begin with a leading 0 prior to the decimal point.)
 
To get around this, this program utilizes BASIC's ability to parse expressions with thecontaining simple mathematicalmath operators, and is in fact technically a self-modifying program. Line 2005 is a line padded with colons which simply allow BASIC to join multiple statements on a single line, otherwise perform no operation. This reserves sufficient space in memory for inserting the user's expression&mdash;by overwriting the first several bytes of colons&mdash;which can then be evaluated in the normal course of the program's execution. The subroutine at 1400 initializes a simple translation table for exchanging the operators into their proper BASIC tokens. Parenthesis, numerals, and variable names do not need to be translated.
 
After the user types in an expression, the program validates the input (same algorithms as the ZX Spectrum example), writes the expression as <code>R=''expression''</code> as tokenized BASIC into line 2005, and then executes the subroutine at 2000 to obtain the value. Upon return, the normal evaluationcontent of whetherthe 24variable was<code>R</code> obtainis evaluated to see if it is checked24.
 
If the statement at line 645 is uncommented, this will allow the program to "erase" line 2005 and thus "hide" the trick. As is, if you list the program after making an attempt, you will see the last expression given to the program.
Line 3,542 ⟶ 3,850:
Since Commodore BASIC v2 was the initial target for this program, all other versions of Commodore BASIC are compatible as long as the base memory address for BASIC programs is adjusted. (BASIC tokens maintain compatibility across all versions.) Simply use the appropriate values for <code>bh</code> and <code>bl</code> in lines 11-15.
 
<langsyntaxhighlight lang=gwbasic>1 rem 24 game
2 rem for rosetta code
10 rem use appropriate basic base address
Line 3,563 ⟶ 3,871:
72 print:print " an arithmetic expression that"
73 print:print " evaluates to a value of 24, however"
74 print:print " you may use only usethe four numbers provided"
75 print:print " given at random by the computer and the"
76 print:print " the standard arithmetic operations of add,"
77 print:print " add, subtract, multiply, and divide. Each"
78 print:print " Each digit must be used by itself. (e.g. if"
79 print:print " (e.g. if given 1, 2, 3, 4, you cannot combine"
80 print:print " combine 1 and 2 to make 12.)"
89 gosub 1000
 
Line 3,618 ⟶ 3,926:
425 get k$:if k$<>"y" and k$<>"n" then 425
430 print k$
435 if k$="y" then goto 1040
440 print:print "Very well. Have a nice day!"
450 end
Line 3,629 ⟶ 3,937:
 
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
Line 3,669 ⟶ 3,977:
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
Line 3,676 ⟶ 3,985:
2005 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2010 return
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,724 ⟶ 4,033:
 
Very well. Have a nice day!
 
ready.
list 2005
 
2005 r=(6-3)*(3+5)::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::
 
ready.
Line 3,729 ⟶ 4,044:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang=lisp>(define-condition choose-digits () ())
(define-condition bad-equation (error) ())
 
Line 3,764 ⟶ 4,079:
(if (= 24 (eval (check (prompt)))) (win) (lose))
(error () (format t "Bad equation, try again.~%"))
(choose-digits () (choose)))))))</langsyntaxhighlight>
 
'''Verbose Implementation'''
 
{{works with|clisp|2.47}}
<langsyntaxhighlight lang=lisp>
(defconstant +ops+ '(* / + -))
 
Line 3,873 ⟶ 4,188:
(emit "Sorry, the form you entered did not ~
compute.~%~%")))))
initially (prompt initial-digits)))</langsyntaxhighlight>
 
Example Usage:
Line 3,904 ⟶ 4,219:
 
=={{header|D}}==
<langsyntaxhighlight lang=d>import std.stdio, std.random, std.math, std.algorithm, std.range,
std.typetuple;
 
Line 3,940 ⟶ 4,255:
writeln("Result: ", stack[0]);
writeln(abs(stack[0] - 24) < 0.001 ? "Good job!" : "Try again.");
}</langsyntaxhighlight>
Example:
<pre>Make 24 with the digits: [1, 8, 9, 8]
Line 3,946 ⟶ 4,261:
Result: 24
Good job!</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Program includes full recursive descent, expression evaluator that can handle any expression the user might eneter.
 
<syntaxhighlight lang="Delphi">
 
 
var ErrorFlag: boolean;
var ErrorStr: string;
 
 
function EvaluateExpression(Express: string): double;
{ Recursive descent expression evaluator }
var Atom: char;
var ExpressStr: string;
var ExpressInx: integer;
const Tab_Char = #$09; SP_char = #$20;
 
procedure HandleError(S: string);
begin
ErrorStr:=S;
ErrorFlag:=True;
Abort;
end;
 
 
procedure GetChar;
begin
if ExpressInx > Length(ExpressStr) then
begin
Atom:= ')';
end
else begin
Atom:= ExpressStr[ExpressInx];
Inc(ExpressInx);
end;
end;
 
 
 
procedure SkipWhiteSpace;
{ Skip Tabs And Spaces In Expression }
begin
while (Atom=TAB_Char) or (Atom=SP_char) do GetChar;
end;
 
 
 
procedure SkipSpaces;
{ Get Next Character, Ignoring Any Space Characters }
begin
repeat GetChar until Atom <> SP_CHAR;
end;
 
 
 
function GetDecimal: integer;
{ Read In A Decimal String And Return Its Value }
var S: string;
begin
Result:=0;
S:='';
while True do
begin
if not (Atom in ['0'..'9']) then break;
S:=S+Atom;
GetChar;
end;
if S='' then HandleError('Number Expected')
else Result:=StrToInt(S);
if Result>9 then HandleError('Only Numbers 0..9 allowed')
end;
 
 
function Expression: double;
{ Returns The Value Of An Expression }
 
 
 
function Factor: double;
{ Returns The Value Of A Factor }
var NEG: boolean;
begin
Result:=0;
while Atom='+' do SkipSpaces; { Ignore Unary "+" }
NEG:= False;
while Atom ='-' do { Unary "-" }
begin
SkipSpaces;
NEG:= not NEG;
end;
 
if (Atom>='0') and (Atom<='9') then Result:= GetDecimal { Unsigned Integer }
else case Atom of
'(': begin { Subexpression }
SkipSpaces;
Result:= Expression;
if Atom<>')' then HandleError('Mismatched Parenthesis');
SkipSpaces;
end;
else HandleError('Syntax Error');
end;
{ Numbers May Terminate With A Space Or Tab }
SkipWhiteSpace;
if NEG then Result:=-Result;
end; { Factor }
 
 
 
function Term: double;
{ Returns Factor * Factor, Etc. }
var R: double;
begin
Result:= Factor;
while True do
case Atom of
'*': begin
SkipSpaces;
Result:= Result * Factor;
end;
'/': begin
SkipSpaces;
R:=Factor;
if R=0 then HandleError('Divide By Zero');
Result:= Result / R;
end;
else break;
end;
end;
{ Term }
 
 
 
function AlgebraicExpression: double;
{ Returns Term + Term, Etc. }
begin
Result:= Term;
while True do
case Atom of
'+': begin SkipSpaces; Result:= Result + Term; end;
'-': begin SkipSpaces; Result:= Result - Term; end
else break;
end;
end; { Algexp }
 
 
 
begin { Expression }
SkipWhiteSpace;
Result:= AlgebraicExpression;
end; { Expression }
 
 
 
begin { EvaluateExpression }
ErrorFlag:=False;
ErrorStr:='';
ExpressStr:=Express;
ExpressInx:=1;
try
GetChar;
Result:= Expression;
except end;
end;
 
 
function WaitForString(Memo: TMemo; Prompt: string): string;
{Wait for key stroke on TMemo component}
var MW: TMemoWaiter;
var C: char;
var Y: integer;
begin
{Use custom object to wait and capture key strokes}
MW:=TMemoWaiter.Create(Memo);
try
Memo.Lines.Add(Prompt);
Memo.SelStart:=Memo.SelStart-1;
Memo.SetFocus;
Result:=MW.WaitForLine;
finally MW.Free; end;
end;
 
 
 
 
 
procedure Play24Game(Memo: TMemo);
{Play the 24 game}
var R: double;
var Nums: array [0..4-1] of char;
var I: integer;
var Express,RS: string;
var RB: boolean;
 
procedure GenerateNumbers;
{Generate and display four random number 1..9}
var S: string;
var I: integer;
begin
{Generate random numbers}
for I:=0 to High(Nums) do
Nums[I]:=char(Random(9)+$31);
{Display them}
S:='';
for I:=0 to High(Nums) do
S:=S+' '+Nums[I];
Memo.Lines.Add('Your Digits: '+S);
end;
 
function TestMatchingNums: boolean;
{Make sure numbers entered by user match the target numbers}
var SL1,SL2: TStringList;
var I: integer;
begin
Result:=False;
SL1:=TStringList.Create;
SL2:=TStringList.Create;
try
{Load target numbers into string list}
for I:=0 to High(Nums) do SL1.Add(Nums[I]);
{Load users expression number int string list}
for I:=1 to Length(Express) do
if Express[I] in ['0'..'9'] then SL2.Add(Express[I]);
{There should be the same number }
if SL1.Count<>SL2.Count then exit;
{Sort them to facilitate testing}
SL1.Sort; SL2.Sort;
{Are number identical, if not exit}
for I:=0 to SL1.Count-1 do
if SL1[I]<>SL2[I] then exit;
{Users numbers passed all tests}
Result:=True;
finally
SL2.Free;
SL1.Free;
end;
end;
 
function TestUserExpression(var S: string): boolean;
{Test expression user entered }
begin
Result:=False;
if not TestMatchingNums then
begin
S:='Numbers Do not Match';
exit;
end;
 
R:=EvaluateExpression(Express);
S:='Expression Value = '+FloatToStrF(R,ffFixed,18,0)+CRLF;
if ErrorFlag then
begin
S:=S+'Expression Problem: '+ErrorStr;
exit;
end;
if R<>24 then
begin
S:=S+'Expression is incorrect value';
exit;
end;
S:=S+'!!!!!! Winner !!!!!!!';
Result:=True;
end;
 
 
begin
Randomize;
Memo.Lines.Add('=========== 24 Game ===========');
GenerateNumbers;
while true do
begin
if Application.Terminated then exit;
Express:=WaitForString(Memo,'Enter expression, Q = quit, N = New numbers: '+CRLF);
if Pos('N',UpperCase(Express))>0 then
begin
GenerateNumbers;
Continue;
end;
if Pos('Q',UpperCase(Express))>0 then exit;
RB:=TestUserExpression(RS);
Memo.Lines.Add(RS);
if not RB then continue;
RS:=WaitForString(Memo,'Play again Y=Yes, N=No'+CRLF);
if Pos('N',UpperCase(RS))>0 then exit;
GenerateNumbers;
end;
end;
 
 
 
 
</syntaxhighlight>
{{out}}
<pre>
=========== 24 Game ===========
Your Digits: 8 2 5 5
Enter expression, Q = quit, N = New numbers:
 
n
 
Your Digits: 3 1 9 3
Enter expression, Q = quit, N = New numbers:
 
3 * 9 -3
 
Numbers Do not Match
Enter expression, Q = quit, N = New numbers:
 
3 * 9 - 3 * 1
 
Expression Value = 24
!!!!!! Winner !!!!!!!
Play again Y=Yes, N=No
 
 
</pre>
 
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang=scheme>
(string-delimiter "")
;; check that nums are in expr, and only once
Line 3,980 ⟶ 4,614:
(writeln "24-game - Can you combine" nums "to get 24 ❓ (q to exit)")
(input-expr check-24 (string-append (string nums) " -> 24 ❓")))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,005 ⟶ 4,639:
 
=={{header|Elena}}==
ELENA 56.0 :
<langsyntaxhighlight lang=elena>import system'routines;
import system'collections;
import system'dynamic;
Line 4,015 ⟶ 4,649:
class ExpressionTree
{
object theTree_tree;
constructor(s)
Line 4,021 ⟶ 4,655:
auto level := new Integer(0);
s.forEach::(ch)
{
var node := new DynamicStruct();
ch =>
$43 { node.Level := level + 1; node.Operation := __subjmssg add } // +
$45 { node.Level := level + 1; node.Operation := __subjmssg subtract } // -
$42 { node.Level := level + 2; node.Operation := __subjmssg multiply } // *
$47 { node.Level := level + 2; node.Operation := __subjmssg divide } // /
$40 { level.append(10); ^ self } // (
$41 { level.reduce(10); ^ self } // )
:! {
node.Leaf := ch.toString().toReal();
node.Level := level + 3
};
if (nil == theTree_tree)
{
theTree_tree := node
}
else
{
if (theTree_tree.Level >= node.Level)
{
node.Left := theTree_tree;
node.Right := nilValuenil;
theTree_tree := node
}
else
{
var top := theTree_tree;
while ((nilValuenil != top.Right)&&(top.Right.Level < node.Level))
{ top := top.Right };
node.Left := top.Right;
node.Right := nilValuenil;
top.Right := node
}
}
Line 4,067 ⟶ 4,701:
eval(node)
{
if (node.containsProperty(subjconstmssg Leaf))
{
^ node.Leaf
Line 4,083 ⟶ 4,717:
get Value()
<= eval(theTree_tree);
readLeaves(list, node)
Line 4,090 ⟶ 4,724:
{ InvalidArgumentException.raise() };
if (node.containsProperty(subjconstmssg Leaf))
{
list.append(node.Leaf)
Line 4,102 ⟶ 4,736:
readLeaves(list)
<= readLeaves(list,theTree_tree);
}
 
Line 4,120 ⟶ 4,754:
theNumbers := new object[]
{
1 + randomGenerator.eval:nextInt(9),
1 + randomGenerator.eval:nextInt(9),
1 + randomGenerator.eval:nextInt(9),
1 + randomGenerator.eval:nextInt(9)
}
}
Line 4,130 ⟶ 4,764:
{
console
.printLine:("------------------------------- Instructions ------------------------------")
.printLine:("Four digits will be displayed.")
.printLine:("Enter an equation using all of those four digits that evaluates to 24")
.printLine:("Only * / + - operators and () are allowed")
.printLine:("Digits can only be used once, but in any order you need.")
.printLine:("Digits cannot be combined - i.e.: 12 + 12 when given 1,2,2,1 is not allowed")
.printLine:("Submit a blank line to skip the current puzzle.")
.printLine:("Type 'q' to quit")
.writeLine()
.printLine:("Example: given 2 3 8 2, answer should resemble 8*3-(2-2)")
.printLine:("------------------------------- --------------------------------------------")
}
prompt()
{
theNumbers.forEach::(n){ console.print(n," ") };
console.print:(": ")
}
Line 4,155 ⟶ 4,789:
var leaves := new ArrayList();
tree.readLeaves:(leaves);
ifnot (leaves.ascendant().sequenceEqual(theNumbers.ascendant()))
{ console.printLine:("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self };
var result := tree.Value;
Line 4,186 ⟶ 4,820:
if (expr == "")
{
console.printLine:("Skipping this puzzle"); self.newPuzzle()
}
else
Line 4,196 ⟶ 4,830:
catch(Exception e)
{
console.printLine:"An error occurred. Check your input and try again."(e)
//console.printLine:"An error occurred. Check your input and try again."
}
};
Line 4,204 ⟶ 4,839:
}
}
 
// --- program ---
 
public program()
Line 4,210 ⟶ 4,847:
 
while (game.prompt().playRound(console.readLine())) {}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 4,236 ⟶ 4,873:
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang=elixir>defmodule Game24 do
def main do
IO.puts "24 Game"
Line 4,274 ⟶ 4,911:
end
 
Game24.main</langsyntaxhighlight>
 
{{out}}
Line 4,289 ⟶ 4,926:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang=Erlang>-module(g24).
-export([main/0]).
 
Line 4,354 ⟶ 4,991:
eval([X|Rest], 0) when X >= $1, X =< $9 ->
eval(Rest, X-$0).
</syntaxhighlight>
</lang>
 
The evaluator uses a simple infix scheme that doesn't care about operator precedence, but does support brackets and parentheses alike. Thus, <code>((9+1)*2)+2+2</code> is evaluated as:
Line 4,386 ⟶ 5,023:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang=fsharp>open System
open System.Text.RegularExpressions
 
Line 4,491 ⟶ 5,128:
loop()
 
gameLoop()</langsyntaxhighlight>
{{out}}
<pre>Compute 24 from the following 4 numbers: 3 3 3 5
Line 4,510 ⟶ 5,147:
 
=={{header|Factor}}==
<langsyntaxhighlight lang=factor>USING:
combinators.short-circuit
continuations
Line 4,552 ⟶ 5,189:
[ '[ _ step ] loop ]
bi ;
</syntaxhighlight>
</lang>
Sample:
<langsyntaxhighlight lang=factor>
IN: scratchpad main
Your numbers are { 4, 1, 8, 2 }, make an expression
8 4 + 2 * 1 /
You got it!
</syntaxhighlight>
</lang>
 
=={{header|Falcon}}==
<langsyntaxhighlight lang=falcon>load compiler
 
function genRandomNumbers( amount )
Line 4,632 ⟶ 5,269:
end
end
end</langsyntaxhighlight>
 
=={{header|Fortran}}==
Line 4,638 ⟶ 5,275:
Indicate operator precedence by parentheses; e.g. (3+(5*6))-9. No whitespace is admissible.
The program uses [[Insertion_sort#Fortran|Insertion_sort in Fortran]].
<langsyntaxhighlight lang=Fortran>program game_24
implicit none
real :: vector(4), reals(11), result, a, b, c, d
Line 4,749 ⟶ 5,386:
 
end program game_24
</syntaxhighlight>
</lang>
 
===As a more general recursive descent parser:===
Permits spaces and arbitrary parentheses.
 
<langsyntaxhighlight lang=FORTRAN>
! implement a recursive descent parser
module evaluate_algebraic_expression
Line 4,965 ⟶ 5,602:
end subroutine deal
end program g24
</syntaxhighlight>
</lang>
 
Compilation and too many examples. Which would you cut?
Line 5,070 ⟶ 5,707:
=={{header|FreeBASIC}}==
Solución en '''RPN''':
<langsyntaxhighlight lang=freebasic>
' The 24 game en FreeBASIC
 
Line 5,179 ⟶ 5,816:
End
'--------------------------
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,202 ⟶ 5,839:
=={{header|GAP}}==
Solution in '''RPN''':
<langsyntaxhighlight lang=gap>Play24 := function()
local input, digits, line, c, chars, stack, stackptr, cur, p, q, ok, a, b, run;
input := InputTextUser();
Line 5,292 ⟶ 5,929:
[ 5, 9, 2, 7 ]
end
gap></langsyntaxhighlight>
 
=={{header|Go}}==
RPN solution.
<langsyntaxhighlight lang=go>package main
 
import (
Line 5,363 ⟶ 6,000:
fmt.Println("correct.")
}
}</langsyntaxhighlight>
Example game:
<pre>
Line 5,372 ⟶ 6,009:
 
=={{header|Gosu}}==
<langsyntaxhighlight lang=Gosu>
uses java.lang.Double
uses java.lang.Integer
Line 5,478 ⟶ 6,115:
print( "You lose!" )
}
</syntaxhighlight>
</lang>
 
=={{header|Groovy}}==
{{trans|Ruby}}
This solution breaks strict adherence to the rules in only one way: any line that starts with the letter "q" causes the game to quit.
<langsyntaxhighlight lang=groovy>final random = new Random()
final input = new Scanner(System.in)
 
Line 5,549 ⟶ 6,186:
println 'One more try, then?'
}
}</langsyntaxhighlight>
 
Sample Run:
Line 5,572 ⟶ 6,209:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=Haskell>import Data.List (sort)
import Data.Char (isDigit)
import Data.Maybe (fromJust)
Line 5,624 ⟶ 6,261:
isOp v = elem v $ fmap fst ops
 
ops = [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))]</langsyntaxhighlight>
 
=={{header|HicEst}}==
<langsyntaxhighlight lang=HicEst>DIMENSION digits(4), input_digits(100), difference(4)
CHARACTER expression*100, prompt*100, answers='Wrong,Correct,', protocol='24 game.txt'
 
Line 5,661 ⟶ 6,298:
DLG(TItle=prompt, Button='>2:Try again', B='>1:New game', B='Quit')
 
END</langsyntaxhighlight>
<langsyntaxhighlight lang=HicEst>4 + 8 + 7 + 5: You used 4 5 7 8 instead 4 4 7 8
4 + 8 + 7 + a: Instead 4 digits you used 3
4 + 8 + 7 + a + 4: a is an illegal character
4 + 8 + 7a + 4: a is an illegal character
4 + 8 + 7 + 4:; answer=Wrong; result=23;
4 * 7 - 8 + 4:; answer=Correct; result=24;</langsyntaxhighlight>
 
=={{header|Huginn}}==
<langsyntaxhighlight lang=huginn>#! /bin/sh
exec huginn --no-argv -E "${0}"
#! huginn
Line 5,723 ⟶ 6,360:
}
return ( 0 );
}</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
This plays the game of 24 using a simplified version of the code from the [[Arithmetic_evaluation#Icon_and_Unicon|Arithmetic evaluation]] task.
<langsyntaxhighlight lang=Icon>invocable all
link strings # for csort, deletec
 
Line 5,784 ⟶ 6,421:
"Combining (concatenating) digits is not allowed.\n",
"Enter 'help', 'quit', or an expression.\n")
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 5,812 ⟶ 6,449:
=={{header|J}}==
 
<langsyntaxhighlight lang=J>require'misc'
deal=: 1 + ? bind 9 9 9 9
rules=: smoutput bind 'see http://en.wikipedia.org/wiki/24_Game'
Line 5,822 ⟶ 6,459:
respond=: (;:'no yes') {::~ wellformed * is24
 
game24=: (respond input)@deal@rules</langsyntaxhighlight>
 
Example use:
Line 5,837 ⟶ 6,474:
=={{header|Java}}==
{{works with|Java|7}}
<langsyntaxhighlight lang=java>import java.util.*;
 
public class Game24 {
Line 5,898 ⟶ 6,535:
return result;
}
}</langsyntaxhighlight>
 
{{out}}
Line 5,907 ⟶ 6,544:
=={{header|JavaScript}}==
 
<langsyntaxhighlight lang=javascript>
function twentyfour(numbers, input) {
var invalidChars = /[^\d\+\*\/\s-\(\)]/;
Line 5,959 ⟶ 6,596:
alert(twentyfour(numbers, input));
}
</syntaxhighlight>
</lang>
 
=={{header|Julia}}==
This implementation, because it is based on the Julia parser and evaluator, allows the user to enter arbitrary infix expressions, including parentheses. (These expressions are checked to ensure that they only include the allowed operations on integer literals.)
<langsyntaxhighlight lang=julia>validexpr(ex::Expr) = ex.head == :call && ex.args[1] in [:*,:/,:+,:-] && all(validexpr, ex.args[2:end])
validexpr(ex::Int) = true
validexpr(ex::Any) = false
Line 5,990 ⟶ 6,627:
end
end
end</langsyntaxhighlight>
{{out}}
<pre>
Line 6,002 ⟶ 6,639:
enter expression using [2,5,8,9] => (8 + 9) + (5 + 2)
you won!</pre>
 
=={{header|Koka}}==
<syntaxhighlight lang=koka>
import std/num/random
import std/os/readline
 
type expr
Num(i: int)
Add(e1: expr, e2: expr)
Sub(e1: expr, e2: expr)
Mul(e1: expr, e2: expr)
Div(e1: expr, e2: expr)
 
fun genNum()
random-int() % 9 + 1
 
fun parseFact(s: string): <div,exn> (expr, string)
match s.head
"(" ->
val (e, rest) = s.tail.parseExpr()
match rest.head
")" -> (e, rest.tail)
_ -> throw("expected ')'")
x | x.head-char.default('_').is-digit -> (Num(x.parse-int.unjust), s.tail)
_ -> throw("No factor")
 
fun parseTerm(s): <div,exn> (expr, string)
val (e', n) = s.parseFact()
match n.head
"*" ->
val (e'', n') = n.tail.parseTerm()
(Mul(e', e''), n')
"/" ->
val (e'', n') = n.tail.parseTerm()
(Div(e', e''), n')
_ -> (e', n)
 
fun parseExpr(s): <div,exn> (expr, string)
val (e', n) = s.parseTerm()
match n.head
"+" ->
val (e'', n') = n.tail.parseExpr()
(Add(e', e''), n')
"-" ->
val (e'', n') = n.tail.parseExpr()
(Sub(e', e''), n')
_ -> (e', n)
 
fun numbers(e: expr): div list<int>
match e
Num(i) -> [i]
Add(e1, e2) -> numbers(e1) ++ numbers(e2)
Sub(e1, e2) -> numbers(e1) ++ numbers(e2)
Mul(e1, e2) -> numbers(e1) ++ numbers(e2)
Div(e1, e2) -> numbers(e1) ++ numbers(e2)
 
fun check(e: expr, l: list<int>): <div,exn> ()
val ns = numbers(e)
if (ns.length == 4) then
if l.all(fn(n) ns.any(fn(x) x == n)) then
()
else
throw("wrong numbers")
else
throw("wrong number of numbers")
 
fun evaluate(e: expr): float64
match e
Num(i) -> i.float64
Add(e1, e2) -> evaluate(e1) + evaluate(e2)
Sub(e1, e2) -> evaluate(e1) - evaluate(e2)
Mul(e1, e2) -> evaluate(e1) * evaluate(e2)
Div(e1, e2) -> evaluate(e1) / evaluate(e2)
 
fun main()
println("\nGoal: ")
println("- Create an expression that evaluates to 24")
println("- Using the four given numbers each number once")
println("- Using the operators (+-/*) with no spaces")
println("Example 2 3 4 1: (2+3)*4*1\n")
println("Here are your numbers!")
var l: list<int> := Nil
repeat(4) fn()
val n = genNum()
l := Cons(n, l)
(n.show ++ " ").print
println("")
var found := False
while { !found } fn()
val (expr, r) = readline().parseExpr()
if r.count > 0 then
println("Expected EOF but got: " ++ r ++ " please try again")
return ()
expr.check(l)
val result = expr.evaluate()
if result == 24.0 then
println("You got it!")
found := True
else
println("Try again, your expression evaluated to: " ++ result.show)
</syntaxhighlight>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang=scala>import java.util.Random
import java.util.Scanner
import java.util.Stack
Line 6,055 ⟶ 6,793:
}
 
fun main(args: Array<String>) = Game24.run()</langsyntaxhighlight>
 
=={{header|Lasso}}==
Line 6,063 ⟶ 6,801:
 
If a valid expression it is evaluated, and the result and success state shown to the user.
<langsyntaxhighlight lang=Lasso>[
if(sys_listunboundmethods !>> 'randoms') => {
define randoms()::array => {
Line 6,132 ⟶ 6,870:
[if(#exprsafe)]
<p>Result: <b>[#exprresult]</b> [#exprcorrect ? 'is CORRECT!' | 'is incorrect']</p>
[/if]</langsyntaxhighlight>
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang=lb>dim d(4)
dim chk(4)
print "The 24 Game"
Line 6,221 ⟶ 6,959:
exit function
[handler]
end function</langsyntaxhighlight>
 
=={{header|LiveCode}}==
Line 6,234 ⟶ 6,972:
4. label button "StartButton"
 
5. Add the following to the code of "StartButton"<langsyntaxhighlight lang=livecode>on mouseUp
put empty into fld "EvalField"
put empty into fld "AnswerField"
put random(9) & comma & random(9) & comma & random(9) & comma & random(9) into fld "YourNumbersField"
end mouseUp</langsyntaxhighlight>
6. Add the following to the code of field "EvalField"<langsyntaxhighlight lang=livecode>
on keyDown k
local ops, nums, allowedKeys, numsCopy, expr
Line 6,269 ⟶ 7,007:
exit keyDown
end if
end keyDown</langsyntaxhighlight>
 
=={{header|Locomotive Basic}}==
 
<langsyntaxhighlight lang=locobasic>10 CLS:RANDOMIZE TIME
20 PRINT "The 24 Game"
30 PRINT "===========":PRINT
Line 6,326 ⟶ 7,064:
520 ' syntax error, e.g. non-matching parentheses
530 PRINT "Error in expression, please try again."
540 RESUME 150</langsyntaxhighlight>
 
Note: The program needs a writable disk in the active disk drive.
Line 6,332 ⟶ 7,070:
=={{header|Logo}}==
{{works with|UCB_Logo|5.5}}
<langsyntaxhighlight lang=logo>; useful constants
make "false 1=0
make "true 1=1
Line 6,405 ⟶ 7,143:
]]]
]
bye</langsyntaxhighlight>
{{out}}
<pre>
Line 6,424 ⟶ 7,162:
 
=={{header|Lua}}==
<langsyntaxhighlight lang=lua>
local function help()
print [[
Line 6,523 ⟶ 7,261:
end
end
game24()</langsyntaxhighlight>
 
Alternately, using the <code>lpeg.re</code> module:
 
<langsyntaxhighlight lang=lua>function twentyfour()
print [[
The 24 Game
Line 6,568 ⟶ 7,306:
end
end
twentyfour()</langsyntaxhighlight>
 
=={{header|Maple}}==
Click [http://maplecloud.maplesoft.com/application.jsp?appId=5764927761416192 here] to try this game online.
<langsyntaxhighlight lang=maple>play24 := module()
export ModuleApply;
local cheating;
Line 6,655 ⟶ 7,393:
end module:
 
play24();</langsyntaxhighlight>
{{out}}
<pre>
Line 6,676 ⟶ 7,414:
Most of the job is already done by Mathematica (the expression conversion); in fact, it is ''too'' good&mdash;it automatically converts ex. 3/4 to Times[3, Power[4, -1]], which we have to specifically test for so that real powers don't get through.
 
<langsyntaxhighlight lang=Mathematica>isLegal[n_List, x_String] :=
Quiet[Check[
With[{h = ToExpression[x, StandardForm, HoldForm]},
Line 6,690 ⟶ 7,428:
"Sorry, that is invalid.", 24, "Congrats! That's 24!", _,
"Sorry, that makes " <> ToString[ToExpression@x, InputForm] <>
", not 24."]]}}]</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
 
<langsyntaxhighlight lang=Matlab> function twentyfour()
N = 4;
n = ceil(rand(1,N)*9);
Line 6,720 ⟶ 7,458:
else
fprintf('expression "%s" does not result in 24 but %i.\n',s,val);
end; </langsyntaxhighlight>
 
=={{header|MiniScript}}==
We use a simple recursive descent parser, with a bit of extra code to make sure that only available digits are used, and all of them are used.
<langsyntaxhighlight lang=MiniScript>evalAddSub = function()
result = evalMultDiv
while true
Line 6,779 ⟶ 7,517:
result = null
while result != 24
availableDigits = choices[0:] // (clones the list)
print "Using only the digits " + availableDigits + ","
tokens = input("enter an expression that comes to 24: ").replace(" ","").values
Line 6,789 ⟶ 7,527:
if result != null then print "That equals " + result + "."
end while
print "Great job!"</langsyntaxhighlight>
 
{{out}}
Line 6,807 ⟶ 7,545:
 
=={{header|mIRC Scripting Language}}==
<langsyntaxhighlight lang=mirc>alias 24 {
dialog -m 24-Game 24-Game
}
Line 6,839 ⟶ 7,577:
did -o 24-Game 1 1 Numbers: $rand(1,9) $rand(1,9) $rand(1,9) $rand(1,9)
}
}</langsyntaxhighlight>
 
=={{header|Modula-2}}==
{{libheader|Ulm's Modula-2 Library}}
<langsyntaxhighlight lang=modula2>MODULE TwentyFour;
 
FROM InOut IMPORT WriteString, WriteLn, Write, ReadString, WriteInt;
Line 7,021 ⟶ 7,759:
END;(*of CASE*)
WriteLn;
END TwentyFour.</langsyntaxhighlight>
 
=={{header|MUMPS}}==
<langsyntaxhighlight lang=mumps>24Game
k number, operator, bracket
; generate 4 random numbers each between 1 & 9
Line 7,104 ⟶ 7,842:
w x
q
</syntaxhighlight>
</lang>
 
=={{header|Nanoquery}}==
<langsyntaxhighlight lang=Nanoquery>import Nanoquery.Lang
import Nanoquery.Util
 
Line 7,190 ⟶ 7,928:
end
end
end</langsyntaxhighlight>
{{out}}
<pre>Your digits are: [2, 5, 4, 6]
Line 7,207 ⟶ 7,945:
{{trans|D}}
{{works with|Nim Compiler|1.0.0}}
<langsyntaxhighlight lang=nim>from random import randomize, rand
from strutils import Whitespace
from algorithm import sort
Line 7,244 ⟶ 7,982:
raise newException(ValueError, "Wrong expression.")
echo "Result: ", stack[0]
echo if abs(stack[0] - 24) < 0.001: "Good job!" else: "Try again."</langsyntaxhighlight>
Example game:
<pre>Make 24 with the digits: @[8, 1, 3, 1]
Line 7,255 ⟶ 7,993:
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/24_game.nit the Nit’s official repository]
 
<langsyntaxhighlight lang=nit>redef class Char
fun is_op: Bool do return "-+/*".has(self)
end
Line 7,403 ⟶ 8,141:
end
 
if random_numbers.has(24) then print "CONGRATULATIONS" else print "YOU LOSE"</langsyntaxhighlight>
 
=={{header|Objeck}}==
{{trans|C++}}
 
<langsyntaxhighlight lang=objeck>use Collection.Generic;
use System.Matrix;
 
Line 7,508 ⟶ 8,246:
alias Func {
Calc : (IntHolder, IntHolder) ~ IntHolder
}</langsyntaxhighlight>
 
=={{header|OCaml}}==
Line 7,515 ⟶ 8,253:
ocamlopt -pp camlp4o g24.ml -o g24.opt
 
<langsyntaxhighlight lang=ocaml>type expression =
| Const of float
| Sum of expression * expression (* e1 + e2 *)
Line 7,604 ⟶ 8,342:
else print_endline "Try again"
end
done</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight lang=Oforth>import: mapping
 
: game
Line 7,629 ⟶ 8,367:
#null? l conform? ifFalse: [ "Sorry, all numbers must be used..." . return ]
24 if=: [ "You won !" ] else: [ "You loose..." ] .
;</langsyntaxhighlight>
 
=={{header|ooRexx}}==
Line 7,640 ⟶ 8,378:
=={{header|OpenEdge/Progress}}==
The dynamic query parser is used to evaluate the expression.
<langsyntaxhighlight lang=Progress (OpenEdge ABL)>DEFINE TEMP-TABLE tt NO-UNDO FIELD ii AS INTEGER.
 
DEFINE VARIABLE p_deanswer AS DECIMAL NO-UNDO.
Line 7,707 ⟶ 8,445:
 
MESSAGE cmessage VIEW-AS ALERT-BOX.
</syntaxhighlight>
</lang>
 
=={{header|PARI/GP}}==
{{untested}}
<langsyntaxhighlight lang=parigp>game()={
my(v=vecsort(vector(4,i,random(8)+1)));
print("Form 24 using */+-() and: "v);
Line 7,755 ⟶ 8,493:
1
)
};</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang=perl>#!/usr/bin/env perl
use warnings;
use strict;
Line 7,803 ⟶ 8,541:
elsif ($n == 24) { say "You win!"; last; }
else { say "Sorry, your expression is $n, not 24"; }
}</langsyntaxhighlight>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #000080;font-style:italic;">-- Note this uses simple/strict left association, so for example:
-- 1+2*1*8 is ((1+2)*1)*8 not 1+((2*1)*8) [or 1+(2*(1*8))], and
Line 7,982 ⟶ 8,720:
<span style="color: #000000;">play</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|PHP}}==
{{trans|Perl}}
<langsyntaxhighlight lang=PHP>#!/usr/bin/env php
The 24 Game
Line 8,079 ⟶ 8,817:
return eval("return $expression;");
}
?></langsyntaxhighlight>
 
=={{header|Picat}}==
<syntaxhighlight lang=Picat>import util.
 
main =>
play.
 
play =>
nl,
Digits = [random() mod 9 + 1 : _ in 1..4].sort(),
println("Enter \"q\" to quit"),
println("Enter \"!\" to request a new set of four digits."),
printf("Or enter expression using %w => ", Digits),
Exp = read_line().strip(),
evaluate(Digits,Exp).
 
evaluate(_Digits,"q") => halt.
evaluate(_Digits,"!") => play.
evaluate(Digits,Exp) =>
Operands = [to_int(D) : D in Exp, digit(D)].sort(),
(Digits !== Operands ->
println("You must use the given digits:" ++ to_string(Digits))
;
catch(Term = parse_term(Exp), Exception, println(Exception)),
Res is Term,
(Res =:= 24 ->
println("Good work!")
;
println("Wong expression")
)
),
play.
</syntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang=PicoLisp>
(load "@lib/frac.l")
 
Line 8,138 ⟶ 8,909:
(loopuntilquit)
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 8,186 ⟶ 8,957:
 
=={{header|PL/I}}==
<langsyntaxhighlight lang=pli>
/* Plays the game of 24. */
 
Line 8,323 ⟶ 9,094:
 
end TWENTYFOUR;
</syntaxhighlight>
</lang>
 
=={{header|Potion}}==
<langsyntaxhighlight lang=Potion>is_num = (s):
x = s ord(0)
if (x >= "0"ord && x <= "9"ord): true.
Line 8,365 ⟶ 9,136:
else:
(entry, " => ", expr string, " != 24") join("") say.
.</langsyntaxhighlight>
 
=={{header|PowerShell}}==
Line 8,372 ⟶ 9,143:
todo: add a validation that all given digits were used. Right now the validation is that 4 digits should be used in the expression, but not exactly the ones given. (example: if you are given the digits 2, 2, 6, 9 this program accepts the following solution: 6 * '''4''' * 2 / 2)
 
<langsyntaxhighlight lang=powershell>
CLS
 
Line 8,446 ⟶ 9,217:
}
While($EndResult -ne 24)
</syntaxhighlight>
</lang>
 
=={{header|ProDOS}}==
This example uses the math module:
<langsyntaxhighlight lang=ProDOS>:a
editvar /modify -random- = <10
printline These are your four digits: -random- -random- -random- -random-
Line 8,460 ⟶ 9,231:
:b
editvar /newvar /value=b /userinput=1 /title=Do you want to play again?
if -b- /hasvalue y goto :a else exitcurrentprogram</langsyntaxhighlight>
 
=={{header|Prolog}}==
{{Works with|GNU Prolog}}
<langsyntaxhighlight lang=prolog>:- initialization(main).
 
 
Line 8,493 ⟶ 9,264:
, ( X == 10 -> Xs = [] ; Xs = [X|Ys], get_line(Ys) )
.
main :- randomize, play, halt.</langsyntaxhighlight>
Example "session":
<pre>Digits: [9,4,6,9]
Line 8,519 ⟶ 9,290:
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang=PureBasic>#digitCount = 4
Global Dim digits(#digitCount - 1) ;holds random digits
 
Line 8,678 ⟶ 9,449:
Print(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
{{out}}
<pre>The 24 Game
Line 8,699 ⟶ 9,470:
===Python: Original, with output===
Uses eval, the built-in expression evaluator of infix expressions.
<langsyntaxhighlight lang=python>'''
The 24 Game
 
Line 8,766 ⟶ 9,537:
print ("Thank you and goodbye")
 
if __name__ == '__main__': main() </langsyntaxhighlight>
 
{{out}}
Line 8,792 ⟶ 9,563:
 
===Python: Alternative===
<langsyntaxhighlight lang=python>import random, re
chars = ["(",")","/","+","-","*"]
while True:
Line 8,824 ⟶ 9,595:
print "You cannot use anthing other than", charsandints
break
print "Thanks for playing"</langsyntaxhighlight>
 
=={{header|Quackery}}==
 
<code>switch</code>, <code>case</code>, and <code>otherwise</code> are defined at [[Metaprogramming#Quackery]].
 
<syntaxhighlight lang=Quackery> [ stack ] is operators ( --> s )
 
0 $ "*/+-" witheach [ bit | ]
operators put
 
[ stack ] is numbers ( --> s )
 
[ 0 swap
witheach [ bit | ]
numbers put ] is putnumbers ( $ --> )
 
[ $ "123456789" shuffle 4 split drop sort ] is choosenumbers ( --> $ )
 
[ say "Using any of the operators * / + -" cr
say "and each of the numbers "
witheach [ emit sp ] say "once," cr
say "enter an RPN expression equal to 24." cr
$ "Spaces between characters are optional: "
input ] is getexpression ( $ --> $ )
 
[ $ "" swap witheach
[ dup space = iff drop else join ] ] is stripspaces ( $ --> $ )
 
[ stack ] is opcount ( --> s )
[ stack ] is numcount ( --> s )
[ stack ] is numsused ( --> s )
 
[ true swap
0 opcount put
0 numcount put
0 numsused put
witheach
[ bit dup numbers share & iff
[ 1 numcount tally
numsused take | numsused put ]
else
[ operators share & if
[ 1 opcount tally ] ]
opcount share numcount share < not if
[ drop false conclude ] ]
numsused take
numbers share != if [ drop false ]
numcount take 4 != if [ drop false ]
opcount take 3 != if [ drop false ] ] is checkexpression ( $ --> b )
 
[ $ "" swap
witheach
[ dup char 0 char 9 1+ within iff
[ join $ " n->v " join ] done
[ switch
char * case [ $ "v* " join ]
char / case [ $ "v/ " join ]
char + case [ $ "v+ " join ]
char - case [ $ "v- " join ]
otherwise [ $ "Error!" fail ] ] ] ] is quackerise ( $ --> [ )
 
[ choosenumbers
dup putnumbers
[ dup getexpression
stripspaces
dup checkexpression not while
cr
say "Badly formed expression. Try again."
cr cr
drop again ]
nip
quackerise
quackery
cr
say "Your expression is equal to "
2dup 10 point$ echo$
24 n->v v- v0= iff
[ say ". :-)" ] else [ say ". :-(" ]
numbers release ] is game ( --> )</syntaxhighlight>
 
{{out}}
 
As a dialogue in the Quackery shell.
 
<pre>O> game
...
Using any of the operators * / + -
and each of the numbers 2 3 8 9 once,
enter an RPN expression equal to 24.
Spaces between characters are optional: 5 7 6 2 * + +
 
Your expression is equal to 24. :-)
Stack empty.
 
/O> game
...
Using any of the operators * / + -
and each of the numbers 2 3 8 9 once,
enter an RPN expression equal to 24.
Spaces between characters are optional: 2 + 5 + 8 + 9
 
Badly formed expression. Try again.
 
Using any of the operators * / + -
and each of the numbers 2 5 8 9 once,
enter an RPN expression equal to 24.
Spaces between characters are optional: 25+8+9+
 
Your expression is equal to 24. :-)
Stack empty.
 
/O> game
...
Using any of the operators * / + -
and each of the numbers 1 3 4 7 once,
enter an RPN expression equal to 24.
Spaces between characters are optional: 1 3 * 4 / 7 +
 
Your expression is equal to 7.75. :-(
Stack empty.
</pre>
 
=={{header|R}}==
This makes use of R's metaprogramming (parse, eval, etc.). It uses parse to obtain a parse tree, which is scanned for containing only permitted elements before evaluating.
 
<langsyntaxhighlight lang=r>twenty.four <- function(operators=c("+", "-", "*", "/", "("),
selector=function() sample(1:9, 4, replace=TRUE),
arguments=selector(),
Line 8,882 ⟶ 9,774:
if (! isTRUE(all.equal(sort(numbers.used), sort(arguments))))
stop("Must use each number once.")
}</langsyntaxhighlight>
Example Session
<langsyntaxhighlight lang=r>> twenty.four()
 
Make 24 out of the numbers 1, 6, 7, 5 and the operators +, -, *, /, ( .
Line 8,913 ⟶ 9,805:
> q
Goodbye!
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 8,921 ⟶ 9,813:
invalid cases.
 
<langsyntaxhighlight lang=racket>
#lang racket
 
Line 8,957 ⟶ 9,849:
result
(error "You didn`t use all numbers!")))
</syntaxhighlight>
</lang>
 
Testing the interpreter:
Line 8,981 ⟶ 9,873:
The program which uses the interpreter to play the game:
 
<langsyntaxhighlight lang=racket>
;; starting the program
(define (start)
Line 9,018 ⟶ 9,910:
(define (read-the-answer)
(read (open-input-string (format "(~a)" (read-line)))))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 9,024 ⟶ 9,916:
 
{{works with|Rakudo|2015.12}}
<syntaxhighlight lang="raku" perl6line>use MONKEY-SEE-NO-EVAL;
 
say "Here are your digits: ",
Line 9,050 ⟶ 9,942:
}
}
</syntaxhighlight>
</lang>
 
The <code>MONKEY-SEE-NO-EVAL</code> pragma enables the dangerous <code>EVAL</code> function, which will compile and execute even user input. In this example, the grammar used to parse the input should ensure that only safe expressions are evaluated.
Line 9,056 ⟶ 9,948:
=={{header|Red}}==
 
<langsyntaxhighlight lang=Red>
Red []
print "Evaluation from left to right with no precedence, unless you use parenthesis." print ""
Line 9,092 ⟶ 9,984:
print "You got it right!"
 
</syntaxhighlight>
</lang>
Output:
<pre>
Line 9,107 ⟶ 9,999:
>>
</pre>
 
===Red: Alternative===
<syntaxhighlight lang=Red>
Red [
Title: "24 Game"
Author: "gltewalt"
]
op: charset "*/+-"
term: [opt "(" num opt ")"]
valid-expression: [term op term op term op term]
 
explode: func [val][
extract/into val 1 c: copy []
]
 
check-expression: does [
if "q" = e: ask "Enter expression: " [halt]
either parse trim/all e valid-expression [
either 24 = m: math to-block form explode e [
print ["You got it!" m]
][
print ["Not quite correct. That's" m]]
][
print "Invalid expression."
]
]
 
main: does [
numbers: collect [loop 4 [keep random 9]]
num: charset form numbers
print [newline "Using the following numbers, enter an expression that equals 24: (pmdas)" numbers]
if none? attempt [check-expression][print "Invalid expression."]
]
 
forever [main]
</syntaxhighlight>
 
=={{header|REXX}}==
Line 9,114 ⟶ 10,043:
This REXX version uses an in─line documentation (for help).
 
<langsyntaxhighlight lang=rexx>/*REXX program helps the user find solutions to the game of 24.
 
╔═════════════════════════════════════════════════════════════════════════════╗
Line 9,361 ⟶ 10,290:
when _v\==0 then call ger 'illegal character:' substr(y, _v, 1)
otherwise nop
end /*select*/</langsyntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, &nbsp; so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
 
Line 9,378 ⟶ 10,307:
 
=={{header|Ring}}==
<langsyntaxhighlight lang=ring>
# Project : 24 game
 
Line 9,439 ⟶ 10,368:
ok
end
</syntaxhighlight>
</lang>
Output:
<pre>
Line 9,456 ⟶ 10,385:
sorry, you used the illegal digit 9
</pre>
 
=={{header|RPL}}==
{{works with|RPL|HP49-C #2.15}}
« '''IF''' DUP TYPE 9. ≠ '''THEN''' { } + <span style="color:grey">@ ''stack contains a number''</span>
'''ELSE'''
'''CASE''' OBJ→ SWAP 2. ≠ '''THEN''' DROP 0 '''END''' <span style="color:grey">@ ''stack contains a monadic operator''</span>
"+-*/" SWAP →STR POS NOT '''THEN''' DROP 0 '''END''' <span style="color:grey">@ ''stack contains a forbidden dyadic operator''</span>
'''END'''
<span style="color:blue">GET4</span> SWAP <span style="color:blue">GET4</span> +
'''END'''
» '<span style="color:blue">GET4</span>' STO <span style="color:grey">@ ''( 'expression' → { numbers } )''</span>
« 1 CF
« RAND 9 * CEIL R→I » 'x' 1 4 1 SEQ SORT <span style="color:grey">@ generate 4 numbers</span>
'''WHILE''' 1 FC? '''REPEAT'''
"Make 24 with" OVER →STR 2 OVER SIZE 2 - SUB +
{ "'" ALG V } INPUT <span style="color:grey">@ asks for an evaluable string</span>
CLLCD DUP TAIL 1 DISP
STR→ DUP <span style="color:blue">GET4</span>
'''CASE''' DUP 0 POS '''THEN''' DROP2 "Forbidden operator" '''END'''
SORT 3 PICK ≠ '''THEN''' DROP "Bad number" '''END'''
EVAL DUP →NUM 3 DISP 24 == '''THEN''' 1 SF "You won!" '''END'''
"Failed to get 24"
'''END'''
2 DISP 2 WAIT
'''END''' DROP
» '<span style="color:blue">GAM24</span>' STO
 
=={{header|Ruby}}==
<langsyntaxhighlight lang=ruby>class Guess < String
def self.play
nums = Array.new(4){rand(1..9)}
Line 9,497 ⟶ 10,453:
end
 
Guess.play</langsyntaxhighlight>
 
=={{header|Rust}}==
Line 9,505 ⟶ 10,461:
So if there is someone better than me please feel free to improve.
{{libheader|rand}}
<langsyntaxhighlight lang=rust>use std::io::{self,BufRead};
extern crate rand;
use rand::Rng;
Line 9,606 ⟶ 10,562:
}
 
}</langsyntaxhighlight>
 
=={{header|Scala}}==
Line 9,614 ⟶ 10,570:
 
Only problems with solution are shown to the user.
<div style='width: full; overflow: scroll'><langsyntaxhighlight lang=scala>object TwentyFourGame {
def main(args: Array[String]) {
import Parser.TwentyFourParser
Line 9,767 ⟶ 10,723:
}
}
}</langsyntaxhighlight></div>
 
{{out}}
Line 9,803 ⟶ 10,759:
This uses read to read in a scheme expression, and eval to evaluate it, so in that sense it's not ideal (eval is evil etc.) but any expression that is valid should be safe and terminate in a timely manner.
 
<langsyntaxhighlight lang=scheme>#lang scheme
(require srfi/27 srfi/1) ;; random-integer, every
 
Line 9,866 ⟶ 10,822:
 
(provide play)
</syntaxhighlight>
</lang>
 
{{out}}
Line 9,899 ⟶ 10,855:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang=ruby>const digits = (1..9 -> pick(4))
const grammar = Regex(
'^ (?&exp) \z
Line 9,934 ⟶ 10,890:
default { say "Sorry, your expression is #{n}, not 24" }
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 9,947 ⟶ 10,903:
 
=={{header|Simula}}==
<langsyntaxhighlight lang=simula>BEGIN
 
CLASS EXPR;
Line 10,243 ⟶ 11,199:
 
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 10,267 ⟶ 11,223:
 
=={{header|Swift}}==
<langsyntaxhighlight lang=swift>import Darwin
import Foundation
 
Line 10,341 ⟶ 11,297:
println("Congratulations, you found a solution!")
}
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{trans|Python}}
This version also terminates cleanly on end-of-file.
<langsyntaxhighlight lang=tcl># Four random non-zero digits
proc choose4 {} {
set digits {}
Line 10,420 ⟶ 11,376:
puts "Thank you and goodbye"
}
main</langsyntaxhighlight>
 
=={{header|TorqueScript}}==
Includes an equation parser to avoid using eval.
To use, type startTwentyFourGame(); in the console.
<langsyntaxhighlight lang=Torque>function startTwentyFourGame()
{
if($numbers !$= "")
Line 10,591 ⟶ 11,547:
}
return %equ;
}</langsyntaxhighlight>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang=tuscript>
$$ MODE TUSCRIPT
BUILD X_TABLE blanks = ":': :"
Line 10,668 ⟶ 11,624:
ENDSECTION
DO game
</syntaxhighlight>
</lang>
{{out}}
<pre style='height:30ex;overflow:scroll'>
Line 10,698 ⟶ 11,654:
=={{header|UNIX Shell}}==
Tried to be POSIX. Not sure about corner-cases.
<langsyntaxhighlight lang=bash>gen_digits() {
awk 'BEGIN { srand()
for(i = 1; i <= 4; i++) print 1 + int(9 * rand())
Line 10,727 ⟶ 11,683:
 
echo $message
done</langsyntaxhighlight>
 
=={{header|VBA}}==
<syntaxhighlight lang=vb>
<lang vb>
Sub Rosetta_24game()
 
Line 10,854 ⟶ 11,810:
End Sub
 
</syntaxhighlight>
</lang>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import os
import rand
import rand.seed
import math
 
fn main() {
rand.seed(seed.time_seed_array(2))
mut n := []int{len: 4}
for i in 0.. n.len {
n[i] = rand.intn(9) or {0}
}
println("Your numbers: $n")
expr := os.input("Enter RPN: ")
if expr.len != 7 {
println("invalid. expression length must be 7." +
" (4 numbers, 3 operators, no spaces)")
return
}
mut stack := []f64{len: 0, cap:4}
for r in expr.split('') {
if r >= '0' && r <= '9' {
if n.len == 0 {
println("too many numbers.")
return
}
mut i := 0
for n[i] != r.int() {
i++
if i == n.len {
println("wrong numbers.")
return
}
}
n.delete(n.index(r.int()))
stack << f64(r[0]-'0'[0])
continue
}
if stack.len < 2 {
println("invalid expression syntax.")
return
}
match r {
'+' {
stack[stack.len-2] += stack[stack.len-1]
}
'-' {
stack[stack.len-2] -= stack[stack.len-1]
}
'*' {
stack[stack.len-2] *= stack[stack.len-1]
}
'/' {
stack[stack.len-2] /= stack[stack.len-1]
}
else {
println("$r invalid.")
return
}
}
stack = stack[..stack.len-1]
}
if math.abs(stack[0]-24) > 1e-6 {
println("incorrect. ${stack[0]} != 24")
} else {
println("correct.")
}
}</syntaxhighlight>
 
{{out}}
Sample game:
<pre>
Make 24 using these digits: [2, 3, 5, 1]
> 23*51-*
Correct!
</pre>
 
=={{header|Wren}}==
Line 10,860 ⟶ 11,894:
{{libheader|Wren-ioutil}}
{{libheader|Wren-seq}}
<langsyntaxhighlight ecmascriptlang="wren">import "random" for Random
import "./ioutil" for Input
import "./seq" for Stack
 
var R = Random.new()
Line 10,906 ⟶ 11,940:
}
 
Game24.run()</langsyntaxhighlight>
 
{{out}}
Line 10,913 ⟶ 11,947:
Make 24 using these digits: [2, 3, 5, 1]
> 23*51-*
Correct!
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">real Stack(10), A, B;
int SP, I, Char, Digit, Digits(10);
 
proc Push(X);
real X;
[Stack(SP):= X; SP:= SP+1];
 
func real Pop;
[SP:= SP-1; return Stack(SP)];
 
[SP:= 0;
for I:= 0 to 9 do Digits(I):= 0;
Text(0, "Enter an RPN expression that equals 24 using all these digits:");
for I:= 0 to 3 do
[Digit:= Ran(9)+1;
ChOut(0, ^ ); ChOut(0, Digit+^0);
Digits(Digit):= Digits(Digit)+1;
];
Text(0, "^m^j> ");
loop [Char:= ChIn(1);
ChOut(0, Char);
if Char >= ^1 and Char <=^9 then
[Digit:= Char - ^0;
Push(float(Digit));
Digits(Digit):= Digits(Digit) - 1;
]
else [if SP >= 2 then [A:= Pop; B:= Pop] else quit;
case Char of
^+: Push(B+A);
^-: Push(B-A);
^*: Push(B*A);
^/: Push(B/A)
other quit;
];
];
CrLf(0);
for I:= 0 to 9 do
if Digits(I) # 0 then
[Text(0, "Must use each of the given digits.^m^j"); exit];
Text(0, if abs(Pop-24.0) < 0.001 then "Correct!" else "Wrong.");
CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
Enter an RPN expression that equals 24 using all these digits: 1 4 4 9
> 44*9+1-
Correct!
</pre>
Line 10,918 ⟶ 12,002:
=={{header|Yabasic}}==
With reverse polish notation
<langsyntaxhighlight lang=Yabasic>operadores$ = "*/+-"
espacios$ = " "
 
Line 11,035 ⟶ 12,119:
until(testigo = false)
return cadena$
end sub</langsyntaxhighlight>
 
{{trans|ZX Spectrum Basic}}
<langsyntaxhighlight lang=Yabasic>do
clear screen
n$=""
Line 11,119 ⟶ 12,203:
return execute(mid$(c$,5,8))
end sub
</syntaxhighlight>
</lang>
 
=={{header|zkl}}==
<langsyntaxhighlight lang=zkl>while(1){
digits := [1..4].pump(String,(0).random.fpM("11-",1,9));
exp := ask("Enter an expression using the digits ",digits,
Line 11,140 ⟶ 12,224:
else println("That evaled to ",r,", not 24");
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 11,156 ⟶ 12,240:
 
=={{header|ZX Spectrum Basic}}==
<langsyntaxhighlight lang=zxbasic>10 LET n$=""
20 RANDOMIZE
30 FOR i=1 TO 4
Line 11,207 ⟶ 12,291:
490 DATA "(nonon)on"
495 DATA "(no(non))on"
500 DATA "no(nonon)"</langsyntaxhighlight>
1,480

edits