24 game/Solve: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(31 intermediate revisions by 13 users not shown)
Line 10:
*   [[Arithmetic Evaluator]]
<br><br>
=={{header|11l}}==
{{trans|Nim}}
 
<syntaxhighlight lang="11l">[Char = ((Float, Float) -> Float)] op
op[Char(‘+’)] = (x, y) -> x + y
op[Char(‘-’)] = (x, y) -> x - y
op[Char(‘*’)] = (x, y) -> x * y
op[Char(‘/’)] = (x, y) -> I y != 0 {x / y} E 9999999
 
F almost_equal(a, b)
R abs(a - b) <= 1e-5
 
F solve(nums)
V syms = ‘+-*/’
V sorted_nums = sorted(nums).map(Float)
L(x, y, z) cart_product(syms, syms, syms)
V n = copy(sorted_nums)
L
V (a, b, c, d) = (n[0], n[1], n[2], n[3])
I almost_equal(:op[x](:op[y](a, b), :op[z](c, d)), 24.0)
R ‘(’a‘ ’y‘ ’b‘) ’x‘ (’c‘ ’z‘ ’d‘)’
I almost_equal(:op[x](a, :op[y](b, :op[z](c, d))), 24.0)
R a‘ ’x‘ (’b‘ ’y‘ (’c‘ ’z‘ ’d‘))’
I almost_equal(:op[x](:op[y](:op[z](c, d), b), a), 24.0)
R ‘((’c‘ ’z‘ ’d‘) ’y‘ ’b‘) ’x‘ ’a
I almost_equal(:op[x](:op[y](b, :op[z](c, d)), a), 24.0)
R ‘(’b‘ ’y‘ (’c‘ ’z‘ ’d‘)) ’x‘’a
I !n.next_permutation()
L.break
R ‘not found’
 
L(nums) [[9, 4, 4, 5],
[1, 7, 2, 7],
[5, 7, 5, 4],
[1, 4, 6, 6],
[2, 3, 7, 3],
[8, 7, 9, 7],
[1, 6, 2, 6],
[7, 9, 4, 1],
[6, 4, 2, 2],
[5, 7, 9, 7],
[3, 3, 8, 8]]
print(‘solve(’nums‘) -> ’solve(nums))</syntaxhighlight>
 
{{out}}
<pre>
solve([9, 4, 4, 5]) -> not found
solve([1, 7, 2, 7]) -> ((7 * 7) - 1) / 2
solve([5, 7, 5, 4]) -> 4 * (7 - (5 / 5))
solve([1, 4, 6, 6]) -> 6 + (6 * (4 - 1))
solve([2, 3, 7, 3]) -> ((2 + 7) * 3) - 3
solve([8, 7, 9, 7]) -> not found
solve([1, 6, 2, 6]) -> 6 + (6 * (1 + 2))
solve([7, 9, 4, 1]) -> (1 - 9) * (4 - 7)
solve([6, 4, 2, 2]) -> (2 - 2) + (4 * 6)
solve([5, 7, 9, 7]) -> (5 + 7) * (9 - 7)
solve([3, 3, 8, 8]) -> 8 / (3 - (8 / 3))
</pre>
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program game24Solvex64.s */
Line 443 ⟶ 502:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 462 ⟶ 521:
New game (y/n) ?
</pre>
 
=={{header|ABAP}}==
Will generate all possible solutions of any given four numbers according to the rules of the 24 game.
 
Note: the permute function was locally from [[Permutations#ABAP|here]]
<langsyntaxhighlight ABAPlang="abap">data: lv_flag type c,
lv_number type i,
lt_numbers type table of i.
Line 663 ⟶ 723:
modify iv_set index lv_perm from lv_temp_2.
modify iv_set index lv_len from lv_temp.
endform.</langsyntaxhighlight>
 
Sample Runs:
Line 956 ⟶ 1,016:
=={{header|Argile}}==
{{works with|Argile|1.0.0}}
<langsyntaxhighlight Argilelang="argile">die "Please give 4 digits as argument 1\n" if argc < 2
 
print a function that given four digits argv[1] subject to the rules of \
Line 1,053 ⟶ 1,113:
(roperators[(rrop[rpn][2])]) (rdigits[3]);
return buffer as text
nil</langsyntaxhighlight>
Examples:
<pre>$ arc 24_game_solve.arg -o 24_game_solve.c
Line 1,067 ⟶ 1,127:
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program game24Solver.s */
Line 1,454 ⟶ 1,514:
.include "../affichage.inc"
 
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 1,483 ⟶ 1,543:
{{works with|AutoHotkey_L}}
Output is in RPN.
<langsyntaxhighlight AHKlang="ahk">#NoEnv
InputBox, NNNN ; user input 4 digits
NNNN := RegExReplace(NNNN, "(\d)(?=\d)", "$1,") ; separate with commas for the sort command
Line 1,590 ⟶ 1,650:
o := A_LoopField o
return o
}</langsyntaxhighlight>
{{out}}for 1127:
<pre>
Line 1,605 ⟶ 1,665:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic">
PROCsolve24("1234")
PROCsolve24("6789")
Line 1,662 ⟶ 1,722:
IF I% > 4 PRINT "No solution found"
ENDPROC
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,670 ⟶ 1,730:
(5+5-6)*6
</pre>
 
=={{header|C}}==
 
Tested with GCC 10.2.0, but should work with all versions supporting C99.<br>
Provided code prints all solutions or nothing in case no solutions are found.<br>
It can be modified or extended to work with more than 4 numbers, goals other than 24 and additional operations.<br>
Note: This a brute-force approach with time complexity <em>O(6<sup>n</sup>.n.(2n-3)!!)</em> and recursion depth <em>n</em>.<br>
 
<syntaxhighlight lang="c">#include <stdio.h>
 
typedef struct {int val, op, left, right;} Node;
 
Node nodes[10000];
int iNodes;
 
int b;
float eval(Node x){
if (x.op != -1){
float l = eval(nodes[x.left]), r = eval(nodes[x.right]);
switch(x.op){
case 0: return l+r;
case 1: return l-r;
case 2: return r-l;
case 3: return l*r;
case 4: return r?l/r:(b=1,0);
case 5: return l?r/l:(b=1,0);
}
}
else return x.val*1.;
}
 
void show(Node x){
if (x.op != -1){
printf("(");
switch(x.op){
case 0: show(nodes[x.left]); printf(" + "); show(nodes[x.right]); break;
case 1: show(nodes[x.left]); printf(" - "); show(nodes[x.right]); break;
case 2: show(nodes[x.right]); printf(" - "); show(nodes[x.left]); break;
case 3: show(nodes[x.left]); printf(" * "); show(nodes[x.right]); break;
case 4: show(nodes[x.left]); printf(" / "); show(nodes[x.right]); break;
case 5: show(nodes[x.right]); printf(" / "); show(nodes[x.left]); break;
}
printf(")");
}
else printf("%d", x.val);
}
 
int float_fix(float x){ return x < 0.00001 && x > -0.00001; }
 
void solutions(int a[], int n, float t, int s){
if (s == n){
b = 0;
float e = eval(nodes[0]);
if (!b && float_fix(e-t)){
show(nodes[0]);
printf("\n");
}
}
else{
nodes[iNodes++] = (typeof(Node)){a[s],-1,-1,-1};
for (int op = 0; op < 6; op++){
int k = iNodes-1;
for (int i = 0; i < k; i++){
nodes[iNodes++] = nodes[i];
nodes[i] = (typeof(Node)){-1,op,iNodes-1,iNodes-2};
solutions(a, n, t, s+1);
nodes[i] = nodes[--iNodes];
}
}
iNodes--;
}
};
 
int main(){
// define problem
 
int a[4] = {8, 3, 8, 3};
float t = 24;
 
// print all solutions
 
nodes[0] = (typeof(Node)){a[0],-1,-1,-1};
iNodes = 1;
 
solutions(a, sizeof(a)/sizeof(int), t, 1);
 
return 0;
}</syntaxhighlight>
 
=={{header|C++}}==
Line 1,677 ⟶ 1,828:
This code may be extended to work with more than 4 numbers, goals other than 24, or different digit ranges. Operations have been manually determined for these parameters, with the belief they are complete.
 
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <ratio>
Line 1,768 ⟶ 1,919:
return 0;
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,819 ⟶ 1,970:
</pre>
 
=={{header|C sharp|C#}}==
Generate binary trees -> generate permutations -> create expression -> evaluate expression<br/>
This works with other targets and more numbers but it will of course become slower.<br/>
Redundant expressions are filtered out (based on https://www.4nums.com/theory/) but I'm not sure I caught them all.
{{works with|C sharp|8}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using static System.Linq.Enumerable;
Line 2,138 ⟶ 2,289:
$"{(wrapLeft ? $"({Left})" : $"{Left}")} {Symbol} {(wrapRight ? $"({Right})" : $"{Right}")}";
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,174 ⟶ 2,325:
=={{header|Ceylon}}==
Don't forget to import ceylon.random in your module.ceylon file.
<langsyntaxhighlight lang="ceylon">import ceylon.random {
DefaultRandom
}
Line 2,306 ⟶ 2,457:
expressions.each(print);
}
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(ns rosettacode.24game.solve
(:require [clojure.math.combinatorics :as c]
[clojure.walk :as w]))
Line 2,333 ⟶ 2,484:
(map println)
doall
count))</langsyntaxhighlight>
 
The function <code>play24</code> works by substituting the given digits and the four operations into the binary tree patterns (o (o n n) (o n n)), (o (o (o n n) n) n), and (o n (o n (o n n))).
Line 2,339 ⟶ 2,490:
 
=={{header|COBOL}}==
<langsyntaxhighlight lang="cobol"> >>SOURCE FORMAT FREE
*> This code is dedicated to the public domain
*> This is GNUCobol 2.0
Line 2,784 ⟶ 2,935:
end-perform
.
end program twentyfoursolve.</langsyntaxhighlight>
 
{{out}}
Line 2,814 ⟶ 2,965:
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
# This program tries to find some way to turn four digits into an arithmetic
# expression that adds up to 24.
Line 2,902 ⟶ 3,053:
solution = solve_24_game a, b, c, d
console.log "Solution for #{[a,b,c,d]}: #{solution ? 'no solution'}"
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,925 ⟶ 3,076:
=={{header|Common Lisp}}==
 
<langsyntaxhighlight lang="lisp">(defconstant +ops+ '(* / + -))
 
(defun digits ()
Line 2,980 ⟶ 3,131:
digits which evaluates to 24. The first form found is returned, or
NIL if there is no solution."
(solvable-p digits))</langsyntaxhighlight>
 
{{out}}
Line 2,998 ⟶ 3,149:
This uses the Rational struct and permutations functions of two other Rosetta Code Tasks.
{{trans|Scala}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.conv, std.string,
std.concurrency, permutations2, arithmetic_rational;
 
Line 3,033 ⟶ 3,184:
foreach (const prob; [[6, 7, 9, 5], [3, 3, 8, 8], [1, 1, 1, 1]])
writeln(prob, ": ", solve(24, prob));
}</langsyntaxhighlight>
{{out}}
<pre>[6, 7, 9, 5]: (6+(9*(7-5)))
Line 3,042 ⟶ 3,193:
The program takes n numbers - not limited to 4 - builds the all possible legal rpn expressions according to the game rules, and evaluates them. Time saving : 4 5 + is the same as 5 4 + . Do not generate twice. Do not generate expressions like 5 6 * + which are not legal.
 
<langsyntaxhighlight lang="scheme">
;; use task [[RPN_to_infix_conversion#EchoLisp]] to print results
(define (rpn->string rpn)
Line 3,154 ⟶ 3,305:
(writeln digits '→ target)
(try-rpn digits target))
</langsyntaxhighlight>
 
{{out}}
Line 3,201 ⟶ 3,352:
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Game24 do
@expressions [ ["((", "", ")", "", ")", ""],
["(", "(", "", "", "))", ""],
Line 3,246 ⟶ 3,397:
IO.puts "found #{length(solutions)} solutions, including #{hd(solutions)}"
IO.inspect Enum.sort(solutions)
end</langsyntaxhighlight>
 
{{out}}
Line 3,267 ⟶ 3,418:
=={{header|ERRE}}==
ERRE hasn't an "EVAL" function so we must write an evaluation routine; this task is solved via "brute-force".
<syntaxhighlight lang="err">
<lang ERR>
PROGRAM 24SOLVE
 
Line 3,579 ⟶ 3,730:
 
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,602 ⟶ 3,753:
Via brute force.
 
<syntaxhighlight lang="euler math toolbox">
<lang Euler Math Toolbox>
>function try24 (v) ...
$n=cols(v);
Line 3,625 ⟶ 3,776:
$return 0;
$endfunction
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="euler math toolbox">
<lang Euler Math Toolbox>
>try24([1,2,3,4]);
Solved the problem
Line 3,648 ⟶ 3,799:
-1+5=4
3-4=-1
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
Line 3,654 ⟶ 3,805:
It eliminates all duplicate solutions which result from transposing equal digits.
The basic solution is an adaption of the OCaml program.
<langsyntaxhighlight lang="fsharp">open System
 
let rec gcd x y = if x = y || x = 0 then y else if x < y then gcd y x else gcd y (x-y)
Line 3,762 ⟶ 3,913:
|> Seq.groupBy id
|> Seq.iter (fun x -> printfn "%s" (fst x))
0</langsyntaxhighlight>
{{out}}
<pre>>solve24 3 3 3 4
Line 3,791 ⟶ 3,942:
=={{header|Factor}}==
Factor is well-suited for this task due to its homoiconicity and because it is a reverse-Polish notation evaluator. All we're doing is grouping each permutation of digits with three selections of the possible operators into quotations (blocks of code that can be stored like sequences). Then we <code>call</code> each quotation and print out the ones that equal 24. The <code>recover</code> word is an exception handler that is used to intercept divide-by-zero errors and continue gracefully by removing those quotations from consideration.
<langsyntaxhighlight lang="factor">USING: continuations grouping io kernel math math.combinatorics
prettyprint quotations random sequences sequences.deep ;
IN: rosetta-code.24-game
Line 3,808 ⟶ 3,959:
print expressions [ [ 24= ] [ 2drop ] recover ] each ;
24-game</langsyntaxhighlight>
{{out}}
<pre>
Line 3,836 ⟶ 3,987:
 
=={{header|Fortran}}==
<langsyntaxhighlight Fortranlang="fortran">program solve_24
use helpers
implicit none
Line 3,904 ⟶ 4,055:
end function op
 
end program solve_24</langsyntaxhighlight>
 
<langsyntaxhighlight Fortranlang="fortran">module helpers
 
contains
Line 3,977 ⟶ 4,128:
end subroutine nextpermutation
 
end module helpers</langsyntaxhighlight>
{{out}} (using g95):
<pre> 3 6 7 9 : 3 *(( 6 - 7 )+ 9 )
Line 3,992 ⟶ 4,143:
2 4 6 8 : (( 2 / 4 )* 6 )* 8
</pre>
 
 
=={{header|FutureBasic}}==
This programme gives just the first-found (simplest) solution. To see the exhaustive list, we would remove the '''if k > 0 then exit fn''' statements.
<syntaxhighlight lang="futurebasic>
 
begin globals
Short k
end globals
 
void local fn eval( t as CFStringRef )
CFMutableStringRef s = fn MutableStringNew
ExpressionRef x = fn ExpressionWithFormat( t )
CFRange r = fn CFRangeMake(0, fn StringLength( t ) )
CFNumberRef n = fn ExpressionValueWithObject( x, Null, Null )
Float f = dblval( n )
if f = 24 // found, so clean up
MutableStringSetString( s, t ) // duplicate string and pretend it was integers all along
MutableStringReplaceOccurrencesOfString( s, @".000000", @"", Null, r )
print s; @" = 24" : k ++
end if
end fn
 
 
clear local fn work( t as CFStringRef )
Short a, b, c, d, e, f, g
CGFloat n(3)
CFStringRef s, os = @"*/+-", o(3)
print t, : k = 0
// Put digits (as floats) and operators (as strings) in arrays
for a = 0 to 3 : s = mid( t, a, 1 ) : n(a) = fn StringFloatValue( s ) : o(a) = mid( os, a, 1 ) : next
// Permutions for the digits ...
for d = 0 to 3 : for e = 0 to 3 : for f = 0 to 3 : for g = 0 to 3
if d != e and d != f and d != g and e != f and e != g and f != g // ... without duplications
// Combinations for the operators (3 from 4, with replacement)
for a = 0 to 3 : for b = 0 to 3 : for c = 0 to 3
fn eval( fn StringWithFormat( @"%f %@ %f %@ %f %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"%f %@ ( %f %@ %f ) %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"%f %@ %f %@ ( %f %@ %f )", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"%f %@ ( %f %@ %f %@ %f )", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"( %f %@ %f ) %@ %f %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"( %f %@ %f %@ %f ) %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"%f %@ ( %f %@ ( %f %@ %f ) )", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"( %f %@ %f ) %@ ( %f %@ %f )", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"( %f %@ ( %f %@ %f )) %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"( ( %f %@ %f ) %@ %f ) %@ %f", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
fn eval( fn StringWithFormat( @"%f %@ ( ( %f %@ %f ) %@ %f )", n(d), o(a), n(e), o(b), n(f), o(c), n(g) ) ) : if k > 0 then exit fn
next : next : next
end if
next : next : next : next
end fn
 
 
window 1, @"24 Game", ( 0, 0, 250, 250 )
fn work(@"3388")
fn work(@"1346")
fn work(@"8752")
 
handleevents
 
</syntaxhighlight>
{{out}}
 
[[File:FB 24.jpg]]
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap"># Solution in '''RPN'''
check := function(x, y, z)
local r, c, s, i, j, k, a, b, p;
Line 4,077 ⟶ 4,292:
# A tricky one:
Player24([3,3,8,8]);
"8383/-/"</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 4,250 ⟶ 4,465:
}
}
}</langsyntaxhighlight>
{{out}}
<pre> 8 6 7 6: No solution
Line 4,265 ⟶ 4,480:
 
=={{header|Gosu}}==
<syntaxhighlight lang="gosu">
<lang Gosu>
uses java.lang.Integer
uses java.lang.Double
Line 4,376 ⟶ 4,591:
print( "No solution!" )
}
</syntaxhighlight>
</lang>
 
=={{header|Haskell}}==
 
<langsyntaxhighlight lang="haskell">import Data.List
import Data.Ratio
import Control.Monad
Line 4,429 ⟶ 4,644:
nub $ permutations $ map Constant r4
 
main = getArgs >>= mapM_ print . solve 24 . map (toEnum . read)</langsyntaxhighlight>
 
Example use:
Line 4,447 ⟶ 4,662:
(8 / (2 / (9 - 3)))</pre>
===Alternative version===
<langsyntaxhighlight lang="haskell">import Control.Applicative
import Data.List
import Text.PrettyPrint
Line 4,488 ⟶ 4,703:
 
main = mapM_ (putStrLn . render . toDoc) $ solve 24 [2,3,8,9]</langsyntaxhighlight>
{{out}}
<pre>((8 / 2) * (9 - 3))
Line 4,504 ⟶ 4,719:
(((9 - 3) * 8) / 2)</pre>
 
== {{header|Icon}} and {{header|Unicon}} ==
This shares code with and solves the [[24_game#Icon_and_Unicon|24 game]]. A series of pattern expressions are built up and then populated with the permutations of the selected digits. Equations are skipped if they have been seen before. The procedure 'eval' was modified to catch zero divides. The solution will find either all occurrences or just the first occurrence of a solution.
 
<langsyntaxhighlight Iconlang="icon">invocable all
link strings # for csort, deletec, permutes
 
Line 4,582 ⟶ 4,797:
suspend 2(="(", E(), =")") | # parenthesized subexpression, or ...
tab(any(&digits)) # just a value
end</langsyntaxhighlight>
 
 
Line 4,589 ⟶ 4,804:
 
=={{header|J}}==
<langsyntaxhighlight Jlang="j">perm=: (A.&i.~ !) 4
ops=: ' ',.'+-*%' {~ >,{i.each 4 4 4
cmask=: 1 + 0j1 * i.@{:@$@[ e. ]
Line 4,597 ⟶ 4,812:
parens=: ], 0 paren 3, 0 paren 5, 2 paren 5, [: 0 paren 7 (0 paren 3)
all=: [: parens [:,/ ops ,@,."1/ perm { [:;":each
answer=: ({.@#~ 24 = ".)@all</langsyntaxhighlight>
 
This implementation tests all 7680 candidate sentences.
Line 4,614 ⟶ 4,829:
Here is an alternative version that supports multi-digit numbers. It prefers expressions without parens, but searches for ones with if needed.
 
<langsyntaxhighlight Jlang="j">ops=: > , { 3#<'+-*%'
perms=: [: ":"0 [: ~. i.@!@# A. ]
build=: 1 : '(#~ 24 = ".) @: u'
Line 4,628 ⟶ 4,843:
if. 0 = #es do. es =. ([: ,/ [: ,/ ops combp"1 2/ perms) build y end.
es -."1 ' '
)</langsyntaxhighlight>
 
{{out}}
Line 4,649 ⟶ 4,864:
 
Note that this version does not extend to different digit ranges.
<langsyntaxhighlight lang="java">import java.util.*;
 
public class Game24Player {
Line 4,912 ⟶ 5,127:
res.add(Arrays.asList((i / npow), (i % npow) / n, i % n));
}
}</langsyntaxhighlight>
 
{{out}}
Line 4,956 ⟶ 5,171:
=={{header|JavaScript}}==
This is a translation of the C code.
<langsyntaxhighlight lang="javascript">var ar=[],order=[0,1,2],op=[],val=[];
var NOVAL=9999,oper="+-*/",out;
 
Line 5,059 ⟶ 5,274:
solve24("1234");
solve24("6789");
solve24("1127");</langsyntaxhighlight>
 
Examples:
Line 5,073 ⟶ 5,288:
 
'''Infrastructure:'''
<langsyntaxhighlight lang="jq"># Generate a stream of the permutations of the input array.
def permutations:
if length == 0 then []
Line 5,110 ⟶ 5,325:
| ($in[$i+1:] | triples) as $tail
| [$head, $in[$i], $tail]
end;</langsyntaxhighlight>
'''Evaluation and pretty-printing of allowed expressions'''
<langsyntaxhighlight lang="jq"># Evaluate the input, which must be a number or a triple: [x, op, y]
def eval:
if type == "array" then
Line 5,134 ⟶ 5,349:
 
def pp:
"\(.)" | explode | map([.] | implode | if . == "," then " " elif . == "\"" then "" else . end) | join("");</langsyntaxhighlight>
 
'''24 Game''':
<langsyntaxhighlight lang="jq">def OPERATORS: ["+", "-", "*", "/"];
 
# Input: an array of 4 digits
Line 5,157 ⟶ 5,372:
;
 
solve(24), "Please try again."</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -r -f Solve.jq
[1,2,3,4]
That was too easy. I found 242 answers, e.g. [4 * [1 + [2 + 3]]]
Line 5,174 ⟶ 5,389:
[1,2,3,4,5,6]
That was too easy. I found 197926 answers, e.g. [[2 * [1 + 4]] + [3 + [5 + 6]]]
Please try again.</langsyntaxhighlight>
 
=={{header|Julia}}==
 
For julia version 0.5 and higher, the Combinatorics package must be installed and imported (`using Combinatorics`). Combinatorial functions like `nthperm` have been moved from Base to that package and are not available by default anymore.
<langsyntaxhighlight lang="julia">function solve24(nums)
length(nums) != 4 && error("Input must be a 4-element Array")
syms = [+,-,*,/]
Line 5,197 ⟶ 5,412:
end
return "0"
end</langsyntaxhighlight>
{{out}}
<pre>julia> for i in 1:10
Line 5,216 ⟶ 5,431:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.util.Random
Line 5,314 ⟶ 5,529:
println(if (solve24(n)) "" else "No solution")
}
}</langsyntaxhighlight>
 
Sample output:
Line 5,331 ⟶ 5,546:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">dim d(4)
input "Enter 4 digits: "; a$
nD=0
Line 5,453 ⟶ 5,668:
exit function
[handler]
end function</langsyntaxhighlight>
 
=={{header|Lua}}==
Line 5,459 ⟶ 5,674:
Generic solver: pass card of any size with 1st argument and target number with second.
 
<langsyntaxhighlight lang="lua">
local SIZE = #arg[1]
local GOAL = tonumber(arg[2]) or 24
Line 5,534 ⟶ 5,749:
 
permgen(input, SIZE)
</syntaxhighlight>
</lang>
 
{{out}}
Line 5,574 ⟶ 5,789:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
The code:
<syntaxhighlight lang="mathematica">
<lang Mathematica>
treeR[n_] := Table[o[trees[a], trees[n - a]], {a, 1, n - 1}]
treeR[1] := n
Line 5,590 ⟶ 5,805:
Permutations[Array[v, 4]], 1]],
Quiet[(# /. v[q_] :> val[[q]]) == 24] &] /.
Table[v[q] -> val[[q]], {q, 4}])]</langsyntaxhighlight>
 
The <code>treeR</code> method recursively computes all possible operator trees for a certain number of inputs. It does this by tabling all combinations of distributions of inputs across the possible values. (For example, <code>treeR[4]</code> is allotted 4 inputs, so it returns <code>{o[treeR[3],treeR[1]],o[treeR[2],treeR[2]],o[treeR[1],treeR[3]]}</code>, where <code>o</code> is the operator (generic at this point).
Line 5,624 ⟶ 5,839:
**For each result, turn the expression into a string (for easy manipulation), strip the "<code>HoldForm</code>" wrapper, replace numbers like "-1*7" with "-7" (a idiosyncrasy of the conversion process), and remove any lingering duplicates. Some duplicates will still remain, notably constructs like "3 - 3" vs. "-3 + 3" and trivially similar expressions like "(8*3)*(6-5)" vs "(8*3)/(6-5)". Example run input and outputs:
 
<langsyntaxhighlight Mathematicalang="mathematica">game24play[RandomInteger[{1, 9}, 4]]</langsyntaxhighlight>
 
{{out}}
Line 5,649 ⟶ 5,864:
An alternative solution operates on Mathematica expressions directly without using any inert intermediate form for the expression tree, but by using <code>Hold</code> to prevent Mathematica from evaluating the expression tree.
 
<langsyntaxhighlight Mathematicalang="mathematica">evaluate[HoldForm[op_[l_, r_]]] := op[evaluate[l], evaluate[r]];
evaluate[x_] := x;
combine[l_, r_ /; evaluate[r] != 0] := {HoldForm[Plus[l, r]],
Line 5,683 ⟶ 5,898:
solveMaintainOrder[1/5, Range[2, 5]]
solveCanPermute[1/5, Range[2, 5]]
solveSubsets[1/5, Range[2, 5]]</langsyntaxhighlight>
 
=={{header|Nim}}==
Line 5,690 ⟶ 5,905:
{{works with|Nim Compiler|0.19.4}}
 
<langsyntaxhighlight lang="nim">import algorithm, sequtils, strformat
 
type
Line 5,745 ⟶ 5,960:
echo fmt"solve({nums}) -> {solve(nums)}"
 
when isMainModule: main()</langsyntaxhighlight>
 
{{out}}
Line 5,764 ⟶ 5,979:
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">type expression =
| Const of float
| Sum of expression * expression (* e1 + e2 *)
Line 5,833 ⟶ 6,048:
| x::xs -> comp x xs
| [] -> assert false
) all</langsyntaxhighlight>
 
<pre>
Line 5,849 ⟶ 6,064:
 
Note: the <code>permute</code> function was taken from [http://faq.perl.org/perlfaq4.html#How_do_I_permute_N_e here]
<langsyntaxhighlight Perllang="perl"># Fischer-Krause ordered permutation generator
# http://faq.perl.org/perlfaq4.html#How_do_I_permute_N_e
sub permute :prototype(&@) {
my $code = shift;
my @idx = 0..$#_;
Line 5,902 ⟶ 6,117:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>E:\Temp>24solve.pl
Line 5,931 ⟶ 6,146:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>--
<span style="color: #000080;font-style:italic;">-- demo\rosetta\24_game_solve.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- =================
<span style="color: #000080;font-style:italic;">-- The following 5 parse expressions are possible.
--
-- Obviously numbers 1234 represent 24 permutations from
-- Write a function that given four digits subject to the rules of the 24 game, computes an expression to solve the game if possible.
-- {1,2,3,4} to {4,3,2,1} of indexes to the real numbers.
-- Show examples of solutions generated by the function
-- Likewise "+-*" is like "123" representing 64 combinations
--
-- from {1,1,1} to {4,4,4} of indexes to "+-*/".
-- The following 5 parse expressions are possible.
-- Both will be replaced if/when the strings get printed.
-- Obviously numbers 1234 represent 24 permutations from
-- Last hint is because of no precedence, just parenthesis.
-- {1,2,3,4} to {4,3,2,1} of indexes to the real numbers.
--</span>
-- Likewise "+-*" is like "123" representing 64 combinations
<span style="color: #008080;">constant</span> <span style="color: #000000;">OPS</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"+-*/"</span>
-- from {1,1,1} to {4,4,4} of indexes to "+-*/".
<span style="color: #008080;">constant</span> <span style="color: #000000;">expressions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"1+(2-(3*4))"</span><span style="color: #0000FF;">,</span>
-- Both will be replaced if/when the strings get printed.
<span style="color: #008000;">"1+((2-3)*4)"</span><span style="color: #0000FF;">,</span>
--
<span style="color: #008000;">"(1+2)-(3*4)"</span><span style="color: #0000FF;">,</span>
constant OPS = "+-*/"
<span style="color: #008000;">"(1+(2-3))*4"</span><span style="color: #0000FF;">,</span>
constant expressions = {"1+(2-(3*4))",
<span style="color: #008000;">"((1+2)-3)*4"</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- (equivalent to "1+2-3*4")
"1+((2-3)*4)",
"(1+2)-(3*4)",
-- The above represented as three sequential operations (the result gets
"(1+(2-3))*4",
-- left in &lt;(map)1&gt;, ie vars[perms[operations[i][3][1]]] aka vars[lhs]):</span>
"((1+2)-3)*4"} -- (equivalent to "1+2-3*4")
<span style="color: #008080;">constant</span> <span style="color: #000000;">operations</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span> <span style="color: #000080;font-style:italic;">--3*=4; 2-=3; 1+=2</span>
--TODO: I'm sure there is a simple (recursive) way to programatically
<span style="color: #0000FF;">{{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span> <span style="color: #000080;font-style:italic;">--2-=3; 2*=4; 1+=2</span>
-- generate the above (for n=2..9) but I'm not seeing it yet...
<span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">}},</span> <span style="color: #000080;font-style:italic;">--1+=2; 3*=4; 1-=3</span>
 
<span style="color: #0000FF;">{{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}},</span> <span style="color: #000080;font-style:italic;">--2-=3; 1+=2; 1*=4</span>
-- The above represented as three sequential operations (the result gets
<span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}}}</span> <span style="color: #000080;font-style:italic;">--1+=2; 1-=3; 1*=4</span>
-- left in <(map)1>, ie vars[perms[operations[i][3][1]]] aka vars[lhs]):
constant operations = {{{3,'*',4},{2,'-',3},{1,'+',2}}, --3*=4; 2-=3; 1+=2
<span style="color: #008080;">function</span> <span style="color: #000000;">evalopset</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">opset</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
{{2,'-',3},{2,'*',4},{1,'+',2}}, --2-=3; 2*=4; 1+=2
<span style="color: #000080;font-style:italic;">-- invoked 5*24*64 = 7680 times, to try all possible expressions/vars/operators
{{1,'+',2},{3,'*',4},{1,'-',3}}, --1+=2; 3*=4; 1-=3
-- (btw, vars is copy-on-write, like all parameters not explicitly returned, so
{{2,'-',3},{1,'+',2},{1,'*',4}}, --2-=3; 1+=2; 1*=4
-- we can safely re-use it without clobbering the callee version.)
{{1,'+',2},{1,'-',3},{1,'*',4}}} --1+=2; 1-=3; 1*=4
-- (update: with js made that illegal and reported it correctly and forced the
--TODO: ... and likewise for parsing "expressions" to yield "operations".
-- addition of the deep_copy(), all exactly the way it should.)</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">lhs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rhs</span>
function evalopset(sequence opset, sequence perms, sequence ops, sequence vars)
<span style="color: #000000;">vars</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
-- invoked 5*24*64 = 7680 times, to try all possible expressions/vars/operators
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">opset</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
-- (btw, vars is copy-on-write, like all parameters not explicitly returned, so
<span style="color: #0000FF;">{</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">opset</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
-- we can safely re-use it without clobbering the callee version.)
<span style="color: #000000;">lhs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span>
integer lhs,op,rhs
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">OPS</span><span style="color: #0000FF;">)]</span>
atom inf
<span style="color: #000000;">rhs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]</span>
for i=1 to length(opset) do
<span style="color: #008080;">if</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span>
{lhs,op,rhs} = opset[i]
<span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]</span>
lhs = perms[lhs]
<span style="color: #008080;">elsif</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span>
op = ops[find(op,OPS)]
<span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]</span>
rhs = perms[rhs]
<span style="color: #008080;">elsif</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'*'</span> <span style="color: #008080;">then</span>
if op='+' then
<span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]</span>
vars[lhs] += vars[rhs]
<span style="color: #008080;">elsif</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'/'</span> <span style="color: #008080;">then</span>
elsif op='-' then
<span style="color: #008080;">if</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">1e300</span><span style="color: #0000FF;">*</span><span style="color: #000000;">1e300</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
vars[lhs] -= vars[rhs]
<span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">]</span>
elsif op='*' then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
vars[lhs] *= vars[rhs]
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
elsif op='/' then
<span style="color: #008080;">return</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">]</span>
if vars[rhs]=0 then inf = 1e300*1e300 return inf end if
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
vars[lhs] /= vars[rhs]
end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">nSolutions</span>
end for
<span style="color: #004080;">sequence</span> <span style="color: #000000;">xSolutions</span>
return vars[lhs]
end function
<span style="color: #008080;">procedure</span> <span style="color: #000000;">success</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer nSolutions
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
sequence xSolutions
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
 
<span style="color: #000000;">expr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">[</span><span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">]]+</span><span style="color: #008000;">'0'</span>
procedure success(string expr, sequence perms, sequence ops, sequence vars, atom r)
<span style="color: #008080;">else</span>
integer ch
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">OPS</span><span style="color: #0000FF;">)</span>
for i=1 to length(expr) do
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span> <span style="color: #008080;">then</span>
ch = expr[i]
<span style="color: #000000;">expr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span>
if ch>='1' and ch<='9' then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
expr[i] = vars[perms[ch-'0']]+'0'
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
ch = find(ch,OPS)
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xSolutions</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
if ch then
<span style="color: #000080;font-style:italic;">-- avoid duplicates for eg {1,1,2,7} because this has found
expr[i] = ops[ch]
-- the "same" solution but with the 1st and 2nd 1s swapped,
end if
-- and likewise whenever an operator is used more than once.</span>
end if
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"success: %s = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)})</span>
end for
<span style="color: #000000;">nSolutions</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
if not find(expr,xSolutions) then
<span style="color: #000000;">xSolutions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xSolutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">)</span>
-- avoid duplicates for eg {1,1,2,7} because this has found
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- the "same" solution but with the 1st and 2nd 1s swapped,
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
-- and likewise whenever an operator is used more than once.
printf(1,"success: %s = %s\n",{expr,sprint(r)})
<span style="color: #008080;">procedure</span> <span style="color: #000000;">tryperms</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
nSolutions += 1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">operations</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
xSolutions = append(xSolutions,expr)
<span style="color: #000080;font-style:italic;">-- 5 parse expressions</span>
end if
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">evalopset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">operations</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1e9</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- fudge tricky 8/(3-(8/3)) case</span>
 
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">24</span> <span style="color: #008080;">then</span>
procedure tryperms(sequence perms, sequence ops, sequence vars)
<span style="color: #000000;">success</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expressions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
atom r
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to length(operations) do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
-- 5 parse expressions
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
r = evalopset(operations[i], perms, ops, vars)
if r=24 then
<span style="color: #008080;">procedure</span> <span style="color: #000000;">tryops</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
success(expressions[i], perms, ops, vars, r)
<span style="color: #008080;">for</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end if
<span style="color: #000080;font-style:italic;">-- 24 var permutations</span>
end for
<span style="color: #000000;">tryperms</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}),</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
include builtins/factorial.e
include builtins/permute.e
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">solve24</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000000;">nSolutions</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
procedure tryops(sequence ops, sequence vars)
<span style="color: #000000;">xSolutions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for p=1 to factorial(4) do
<span style="color: #008080;">for</span> <span style="color: #000000;">op1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
-- 24 var permutations
<span style="color: #008080;">for</span> <span style="color: #000000;">op2</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
tryperms(permute(p,{1,2,3,4}),ops, vars)
<span style="color: #008080;">for</span> <span style="color: #000000;">op3</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000080;font-style:italic;">-- 64 operator combinations</span>
end procedure
<span style="color: #000000;">tryops</span><span style="color: #0000FF;">({</span><span style="color: #000000;">OPS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">OPS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">OPS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op3</span><span style="color: #0000FF;">]},</span><span style="color: #000000;">vars</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
global procedure solve24(sequence vars)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
nSolutions = 0
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
xSolutions = {}
for op1=1 to 4 do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n%d solutions\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">nSolutions</span><span style="color: #0000FF;">})</span>
for op2=1 to 4 do
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
for op3=1 to 4 do
-- 64 operator combinations
<span style="color: #000000;">solve24</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">})</span>
tryops({OPS[op1],OPS[op2],OPS[op3]},vars)
<span style="color: #000080;font-style:italic;">--solve24({6,4,6,1})
end for
--solve24({3,3,8,8})
end for
--solve24({6,9,7,4})</span>
end for
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
 
<!--</syntaxhighlight>-->
printf(1,"\n%d solutions\n",{nSolutions})
end procedure
 
solve24({1,1,2,7})
if getc(0) then end if</lang>
{{out}}
<pre>
Line 6,067 ⟶ 6,278:
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">main =>
<lang Picat>import util.
foreach (_ in 1..10)
Nums = [D : _ in 1..4, D = random() mod 9 + 1],
NumExps = [(D,D) : D in Nums],
println(Nums),
(solve(NumExps) -> true; println("No solution")),
nl
end.
 
solve([(Num,Exp)]), Num =:= 24 =>
println(Exp).
solve(NumExps) =>
select((Num1,Exp1),NumExps,NumExps1),
select((Num2,Exp2),NumExps1,NumExps2),
member(Op, ['+','-','*','/']),
(Op == '/' -> Num2 =\= 0; true),
Num3 = apply(Op,Num1,Num2),
Exp3 =.. [Op,Exp1,Exp2],
solve([(Num3,Exp3)|NumExps2]).
</syntaxhighlight>
 
{{trans|Raku}}
<syntaxhighlight lang="picat">import util.
 
main =>
Line 6,110 ⟶ 6,343:
R := replace(R, F,T.to_string())
end,
Res = R.</syntaxhighlight>
 
</lang>
 
Test:
 
{{out}}
<pre>
Picat> main
Line 6,143 ⟶ 6,373:
(8 * 6) / (7 - 5)
8 * (6 / (7 - 5))
len = 24</pre>
 
</pre>
 
Another approach:
 
<langsyntaxhighlight Picatlang="picat">import util.
 
main =>
Line 6,156 ⟶ 6,384:
_ = findall(Expr, solve_num2(Nums,Target)),
nl.
 
 
solve_num2(Nums, Target) =>
Line 6,195 ⟶ 6,422:
check(A,X,B,Y,C,Z,D,Target,Expr) =>
Expr = [A,X,"(","(",B,Y,C,")", Z,D,")"].to_string2(),
Target =:= Expr.eval().</syntaxhighlight>
</lang>
 
{{out}}
Test:
<pre>> main
 
<pre>
> main
6*(5+(7-8)) = 24
6*(7+(5-8)) = 24
Line 6,219 ⟶ 6,443:
8/((7-5)/6) = 24
(6*8)/(7-5) = 24
(8*6)/(7-5) = 24</pre>
 
</pre>
 
=={{header|PicoLisp}}==
We use Pilog (PicoLisp Prolog) to solve this task
<langsyntaxhighlight PicoLisplang="picolisp">(be play24 (@Lst @Expr) # Define Pilog rule
(permute @Lst (@A @B @C @D))
(member @Op1 (+ - * /))
Line 6,242 ⟶ 6,464:
(println @X) ) )
 
(play24 5 6 7 8) # Call 'play24' function</langsyntaxhighlight>
{{out}}
<pre>(* (+ 5 7) (- 8 6))
Line 6,261 ⟶ 6,483:
Note
This example uses the math module:
<langsyntaxhighlight ProDOSlang="prodos">editvar /modify -random- = <10
:a
editvar /newvar /withothervar /value=-random- /title=1
Line 6,295 ⟶ 6,517:
printline you could have done it by doing -c-
stoptask
goto :b</langsyntaxhighlight>
 
{{out}}
Line 6,316 ⟶ 6,538:
rdiv/2 is use instead of //2 to enable the program to solve difficult cases as [3 3 8 8].
 
<langsyntaxhighlight Prologlang="prolog">play24(Len, Range, Goal) :-
game(Len, Range, Goal, L, S),
maplist(my_write, L),
Line 6,406 ⟶ 6,628:
 
my_write(V) :-
format('~w ', [V]).</langsyntaxhighlight>
{{out}}
<pre>?- play24(4,9, 24).
Line 6,466 ⟶ 6,688:
{{Works with|GNU Prolog|1.4.4}}
Little efforts to remove duplicates (e.g. output for [4,6,9,9]).
<langsyntaxhighlight lang="prolog">:- initialization(main).
 
solve(N,Xs,Ast) :-
Line 6,487 ⟶ 6,709:
 
test(T) :- solve(24, [2,3,8,9], T).
main :- forall(test(T), (write(T), nl)), halt.</langsyntaxhighlight>
{{Output}}
<pre>(9-3)*8//2
Line 6,507 ⟶ 6,729:
The function is called '''solve''', and is integrated into the game player.
The docstring of the solve function shows examples of its use when isolated at the Python command line.
<syntaxhighlight lang="python">'''
<lang Python>'''
The 24 Game Player
Line 6,665 ⟶ 6,887:
print ("Thank you and goodbye")
main()</langsyntaxhighlight>
 
{{out}}
Line 6,690 ⟶ 6,912:
Thank you and goodbye</pre>
 
====Difficult case requiring precise division====
 
The digits 3,3,8 and 8 have a solution that is not equal to 24 when using Pythons double-precision floating point because of a division in all answers.
Line 6,719 ⟶ 6,941:
==={{header|Python}} Succinct===
Based on the Julia example above.
<langsyntaxhighlight lang="python"># -*- coding: utf-8 -*-
import operator
from itertools import product, permutations
Line 6,757 ⟶ 6,979:
[3,3,8,8], # Difficult case requiring precise division
]:
print(f"solve24({nums}) -> {solve24(nums)}")</langsyntaxhighlight>
 
{{out}}
Line 6,774 ⟶ 6,996:
==={{header|Python}} Recursive ===
This works for any amount of numbers by recursively picking two and merging them using all available operands until there is only one value left.
<langsyntaxhighlight lang="python"># -*- coding: utf-8 -*-
# Python 3
from operator import mul, sub, add
Line 6,818 ⟶ 7,040:
except StopIteration:
print("No solution found")
</syntaxhighlight>
</lang>
 
{{out}}
Line 6,835 ⟶ 7,057:
===Python: using tkinter===
 
<langsyntaxhighlight lang="python">
''' Python 3.6.5 code using Tkinter graphical user interface.
Combination of '24 game' and '24 game/Solve'
Line 6,872 ⟶ 7,094:
 
self.hdg = Label(self.top_fr,
text=' 2124 Game ',
font='arial 22 bold',
fg='navy',
Line 7,195 ⟶ 7,417:
g = Game(root)
root.mainloop()
</syntaxhighlight>
</lang>
 
=={{header|Quackery}}==
 
<code>permutations</code> is defined at [[Permutations#Quackery]] and <code>uniquewith</code> is defined at [[Remove duplicate elements#Quackery]].
 
<syntaxhighlight lang="quackery"> [ ' [ 0 1 2 3 ]
permutations ] constant is numorders ( --> [ )
 
[ []
4 3 ** times
[ [] i^
3 times
[ 4 /mod 4 +
rot join swap ]
drop
nested join ] ] constant is oporders ( --> [ )
 
[ [] numorders witheach
[ oporders witheach
[ dip dup join nested
rot swap join swap ]
drop ] ] constant is allorders ( --> [ )
 
[ [] unrot witheach
[ dip dup peek
swap dip [ nested join ] ]
drop ] is reorder ( [ [ --> [ )
 
[ ' [ [ 0 1 4 2 5 3 6 ]
[ 0 1 4 2 3 5 6 ]
[ 0 1 2 4 3 5 6 ] ]
witheach
[ dip dup reorder swap ]
4 pack ] is orderings ( [ --> [ )
 
[ witheach
[ dup number? iff n->v done
dup ' + = iff
[ drop v+ ] done
dup ' - = iff
[ drop v- ] done
' * = iff v* done
v/ ]
24 n->v v- v0= ] is 24= ( [ --> b )
 
[ 4 pack sort
[] swap
' [ + - * / ] join
allorders witheach
[ dip dup reorder orderings
witheach
[ dup 24= iff
[ rot swap
nested join swap ]
else drop ] ]
drop
uniquewith
[ dip unbuild unbuild $> ]
dup size
dup 0 = iff
[ 2drop say "No solutions." ]
done
dup 1 = iff
[ drop say "1 solution." ]
else
[ echo say " solutions." ]
unbuild
2 split nip
-2 split drop nest$ 90 wrap$ ] is solve ( n n n n --> )</syntaxhighlight>
 
{{out}}
 
As a dialogue in the Quackery shell.
 
<pre>/O> 8 8 3 3 solve
...
1 solution.
[ 8 3 8 3 / - / ]
Stack empty.
 
/O> 7 7 9 4 solve
...
No solutions.
Stack empty.
 
/O> 8 7 6 5 solve
...
22 solutions.
[ 5 7 + 8 6 - * ] [ 5 7 + 8 - 6 * ] [ 5 8 - 7 + 6 * ] [ 6 5 7 8 - + * ] [ 6 5 7 + 8 - * ]
[ 6 5 8 7 - - * ] [ 6 5 8 - 7 + * ] [ 6 7 5 8 - + * ] [ 6 7 5 + 8 - * ] [ 6 7 5 - 8 / / ]
[ 6 7 8 5 - - * ] [ 6 7 8 - 5 + * ] [ 6 8 7 5 - / * ] [ 6 8 * 7 5 - / ] [ 7 5 + 8 6 - * ]
[ 7 5 + 8 - 6 * ] [ 7 8 - 5 + 6 * ] [ 8 6 7 5 - / * ] [ 8 6 - 5 7 + * ] [ 8 6 - 7 5 + * ]
[ 8 6 * 7 5 - / ] [ 8 7 5 - 6 / / ]
Stack empty.
</pre>
 
=={{header|R}}==
This uses exhaustive search and makes use of R's ability to work with expressions as data. It is in principle general for any set of operands and binary operators.
<syntaxhighlight lang="r">
<lang r>
library(gtools)
 
Line 7,234 ⟶ 7,551:
return(NA)
}
</syntaxhighlight>
</lang>
{{out}}
<syntaxhighlight lang="r">
<lang r>
> solve24()
8 * (4 - 2 + 1)
Line 7,249 ⟶ 7,566:
> solve24(ops=c('-', '/')) #restricted set of operators
(8 - 2)/(1/4)
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
The sequence of all possible variants of expressions with given numbers ''n1, n2, n3, n4'' and operations ''o1, o2, o3''.
<langsyntaxhighlight lang="racket">
(define (in-variants n1 o1 n2 o2 n3 o3 n4)
(let ([o1n (object-name o1)]
Line 7,270 ⟶ 7,587:
`(,n1 ,o1n ((,n2 ,o3n ,n3) ,o2n ,n4))
`(,n1 ,o1n (,n2 ,o2n (,n3 ,o3n ,n4))))))))
</syntaxhighlight>
</lang>
 
Search for all solutions using brute force:
<langsyntaxhighlight lang="racket">
(define (find-solutions numbers (goal 24))
(define in-operations (list + - * /))
Line 7,289 ⟶ 7,606:
 
(define (remove-from numbers . n) (foldr remq numbers n))
</syntaxhighlight>
</lang>
 
Examples:
Line 7,320 ⟶ 7,637:
Since Raku uses Rational numbers for division (whenever possible) there is no loss of precision as is common with floating point division. So a comparison like (1 + 7) / (1 / 3) == 24 "Just Works"<sup>&trade;</sup>
 
<syntaxhighlight lang="raku" perl6line>use MONKEY-SEE-NO-EVAL;
 
my @digits;
Line 7,349 ⟶ 7,666:
 
# Brute force test the different permutations
(unique @digits.permutations)».join.unique».comb.race.map: -> @p {
for @ops -> @o {
for @formats -> $format {
my $result = .EVAL given my $string = sprintf $format, flat roundrobin(|@p;, |@o, :slip);
my $result = EVAL($string);
say "$string = 24" and last if $result and $result == 24;
}
}
}</syntaxhighlight>
}
 
# Only return unique sub-arrays
sub unique (@array) {
my %h = map { $_.Str => $_ }, @array;
%h.values;
}</lang>
 
{{out}}
<pre>
Line 7,415 ⟶ 7,724:
Alternately, a version that doesn't use EVAL. More general case. Able to handle 3 or 4 integers, able to select the goal value.
 
<syntaxhighlight lang="raku" perl6line>my %*SUB-MAIN-OPTS = :named-anywhere;
 
sub MAIN (*@parameters, Int :$goal = 24) {
Line 7,504 ⟶ 7,813:
demo and will show this message.\e[0m
========================================================================
}</langsyntaxhighlight>
{{out}}
When supplied 1399 on the command line:
Line 7,518 ⟶ 7,827:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program helps the user find solutions to the game of 24. */
/* start-of-help
┌───────────────────────────────────────────────────────────────────────┐
Line 7,780 ⟶ 8,089:
ger: say= '***error*** for argument:' y; say arg(1); errCode= 1; return 0
p: return word( arg(1), 1)
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1)</langsyntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here ──► &nbsp; &nbsp; [[CHANGESTR.REX]].
<br><br>
Line 7,893 ⟶ 8,202:
{{trans|Tcl}}
{{works with|Ruby|2.1}}
<langsyntaxhighlight lang="ruby">class TwentyFourGame
EXPRESSIONS = [
'((%dr %s %dr) %s %dr) %s %dr',
Line 7,933 ⟶ 8,242:
puts "found #{solutions.size} solutions, including #{solutions.first}"
puts solutions.sort
end</langsyntaxhighlight>
 
{{out}}
Line 7,967 ⟶ 8,276:
=={{header|Rust}}==
{{works with|Rust|1.17}}
<langsyntaxhighlight lang="rust">#[derive(Clone, Copy, Debug)]
enum Operator {
Sub,
Line 8,132 ⟶ 8,441:
[numbers[order[0]], numbers[order[1]], numbers[order[2]], numbers[order[3]]]
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 8,146 ⟶ 8,455:
A non-interactive player.
 
<langsyntaxhighlight lang="scala">def permute(l: List[Double]): List[List[Double]] = l match {
case Nil => List(Nil)
case x :: xs =>
Line 8,170 ⟶ 8,479:
}
 
def hasSolution(l: List[Double]) = permute(l) flatMap computeAllOperations filter (_._1 == 24) map (_._2)</langsyntaxhighlight>
 
Example:
Line 8,204 ⟶ 8,513:
This version outputs an S-expression that will '''eval''' to 24 (rather than converting to infix notation).
 
<langsyntaxhighlight lang="scheme">
#!r6rs
 
Line 8,251 ⟶ 8,560:
(filter evaluates-to-24
(map* tree (iota 6) ops ops ops perms))))
</syntaxhighlight>
</lang>
 
Example output:
<langsyntaxhighlight lang="scheme">
> (solve 1 3 5 7)
((* (+ 1 5) (- 7 3))
Line 8,268 ⟶ 8,577:
> (solve 3 4 9 10)
()
</syntaxhighlight>
</lang>
 
=={{header|Sidef}}==
Line 8,274 ⟶ 8,583:
'''With eval():'''
 
<langsyntaxhighlight lang="ruby">var formats = [
'((%d %s %d) %s %d) %s %d',
'(%d %s (%d %s %d)) %s %d',
Line 8,306 ⟶ 8,615:
}
}
}</langsyntaxhighlight>
 
'''Without eval():'''
<langsyntaxhighlight lang="ruby">var formats = [
{|a,b,c|
Hash(
Line 8,366 ⟶ 8,675:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 8,383 ⟶ 8,692:
 
=={{header|Simula}}==
<langsyntaxhighlight lang="simula">BEGIN
 
 
Line 8,680 ⟶ 8,989:
OUTIMAGE;
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 8,699 ⟶ 9,008:
=={{header|Swift}}==
 
<langsyntaxhighlight lang="swift">
import Darwin
import Foundation
Line 8,871 ⟶ 9,180:
} else {
println("Congratulations, you found a solution!")
}</langsyntaxhighlight>
 
{{out}}The program in action:
Line 8,918 ⟶ 9,227:
This is a complete Tcl script, intended to be invoked from the command line.
{{tcllib|struct::list}}
<langsyntaxhighlight lang="tcl">package require struct::list
# Encoding the various expression trees that are possible
set patterns {
Line 8,979 ⟶ 9,288:
}
}
print24GameSolutionFor $argv</langsyntaxhighlight>
{{out}}
Demonstrating it in use:
Line 9,000 ⟶ 9,309:
non-terminal nodes of a tree in every possible way. The <code>value</code> function evaluates a tree and the
<code>format</code> function displays it in a readable form.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import rat
Line 9,010 ⟶ 9,319:
format = *^ ~&v?\-+~&h,%zP@d+- ^H/mat@d *v ~&t?\~& :/`(+ --')'
 
game"n" "d" = format* value==("n",1)*~ with_roots/'+-*/' with_leaves/"d"*-1 tree_shapes length "d"</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">#show+
 
test_games = mat` * pad` *K7 pad0 game24* <<2,3,8,9>,<5,7,4,1>,<5,6,7,8>></langsyntaxhighlight>
output:
<pre>
Line 9,045 ⟶ 9,354:
((7-8)+5)*6
((5-8)+7)*6
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="wren">import "random" for Random
import "./dynamic" for Tuple, Enum, Struct
 
var N_CARDS = 4
var SOLVE_GOAL = 24
var MAX_DIGIT = 9
 
var Frac = Tuple.create("Frac", ["num", "den"])
 
var OpType = Enum.create("OpType", ["NUM", "ADD", "SUB", "MUL", "DIV"])
 
var Expr = Struct.create("Expr", ["op", "left", "right", "value"])
 
var showExpr // recursive function
showExpr = Fn.new { |e, prec, isRight|
if (!e) return
if (e.op == OpType.NUM) {
System.write(e.value)
return
}
var op = (e.op == OpType.ADD) ? " + " :
(e.op == OpType.SUB) ? " - " :
(e.op == OpType.MUL) ? " x " :
(e.op == OpType.DIV) ? " / " : e.op
if ((e.op == prec && isRight) || e.op < prec) System.write("(")
showExpr.call(e.left, e.op, false)
System.write(op)
showExpr.call(e.right, e.op, true)
if ((e.op == prec && isRight) || e.op < prec) System.write(")")
}
 
var evalExpr // recursive function
evalExpr = Fn.new { |e|
if (!e) return Frac.new(0, 1)
if (e.op == OpType.NUM) return Frac.new(e.value, 1)
var l = evalExpr.call(e.left)
var r = evalExpr.call(e.right)
var res = (e.op == OpType.ADD) ? Frac.new(l.num * r.den + l.den * r.num, l.den * r.den) :
(e.op == OpType.SUB) ? Frac.new(l.num * r.den - l.den * r.num, l.den * r.den) :
(e.op == OpType.MUL) ? Frac.new(l.num * r.num, l.den * r.den) :
(e.op == OpType.DIV) ? Frac.new(l.num * r.den, l.den * r.num) :
Fiber.abort("Unknown op: %(e.op)")
return res
}
 
var solve // recursive function
solve = Fn.new { |ea, len|
if (len == 1) {
var final = evalExpr.call(ea[0])
if (final.num == final.den * SOLVE_GOAL && final.den != 0) {
showExpr.call(ea[0], OpType.NUM, false)
return true
}
}
var ex = List.filled(N_CARDS, null)
for (i in 0...len - 1) {
for (j in i + 1...len) ex[j - 1] = ea[j]
var node = Expr.new(OpType.NUM, null, null, 0)
ex[i] = node
for (j in i + 1...len) {
node.left = ea[i]
node.right = ea[j]
for (k in OpType.startsFrom+1...OpType.members.count) {
node.op = k
if (solve.call(ex, len - 1)) return true
}
node.left = ea[j]
node.right = ea[i]
node.op = OpType.SUB
if (solve.call(ex, len - 1)) return true
node.op = OpType.DIV
if (solve.call(ex, len - 1)) return true
ex[j] = ea[j]
}
ex[i] = ea[i]
}
return false
}
 
var solve24 = Fn.new { |n|
var l = List.filled(N_CARDS, null)
for (i in 0...N_CARDS) l[i] = Expr.new(OpType.NUM, null, null, n[i])
return solve.call(l, N_CARDS)
}
 
var r = Random.new()
var n = List.filled(N_CARDS, 0)
for (j in 0..9) {
for (i in 0...N_CARDS) {
n[i] = 1 + r.int(MAX_DIGIT)
System.write(" %(n[i])")
}
System.write(": ")
System.print(solve24.call(n) ? "" : "No solution")
}</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
5 4 2 6: (5 + 4) x 2 + 6
5 3 2 9: (5 - 2) x 9 - 3
4 8 4 3: ((4 + 8) - 4) x 3
3 8 4 7: 8 - (3 - 7) x 4
7 9 9 2: No solution
1 6 5 5: (1 + 5) x 5 - 6
3 2 7 8: (8 - (3 - 7)) x 2
2 2 8 8: (2 + 2) x 8 - 8
6 4 2 5: (6 - 2) x 5 + 4
9 2 1 6: 9 x 2 x 1 + 6
</pre>
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">operators$ = "*+-/"
space$ = " "
 
Line 9,226 ⟶ 9,649:
next n
return true
end sub</langsyntaxhighlight>
 
=={{header|zkl}}==
Line 9,232 ⟶ 9,655:
 
File solve24.zkl:
<langsyntaxhighlight lang="zkl">var [const] H=Utils.Helpers;
fcn u(xs){ xs.reduce(fcn(us,s){us.holds(s) and us or us.append(s) },L()) }
var ops=u(H.combosK(3,"+-*/".split("")).apply(H.permute).flatten());
Line 9,257 ⟶ 9,680:
catch(MathError){ False } };
{ f2s(digits4,ops3,f) }]];
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">solutions:=u(game24Solver(ask(0,"digits: ")));
println(solutions.len()," solutions:");
solutions.apply2(Console.println);</langsyntaxhighlight>
One trick used is to look at the solving functions name and use the digit in it to index into the formats list.
{{out}}
Line 9,285 ⟶ 9,708:
...
</pre>
 
[[Category:Puzzles]]
 
{{omit from|GUISS}}
{{omit from|ML/I}}
 
[[Category:Puzzles]]
9,476

edits