24 game/Solve: Difference between revisions

Content added Content deleted
(→‎{{header|C}}: added odd example output)
Line 1,825: Line 1,825:
(/ (* 8 6) (- 7 5))</pre>
(/ (* 8 6) (- 7 5))</pre>


=={{header|Prolog}}==
Works with SWI-Prolog.<BR>
The game is generic, you can choose to play with a goal different of 24, any number of numbers in other ranges than 1 .. 9 ! <BR>
rdiv/2 is use instead of //2 to enable the program to solve difficult cases as [3 3 8 8].

<lang Prolog>play24(Len, Range, Goal) :-
game(Len, Range, Goal, L, S),
maplist(my_write, L),
format(': ~w~n', [S]).

game(Len, Range, Value, L, S) :-
length(L, Len),
maplist(choose(Range), L),
compute(L, Value, [], S).


choose(Range, V) :-
V is random(Range) + 1.


write_tree([M], [M]).

write_tree([+, M, N], S) :-
write_tree(M, MS),
write_tree(N, NS),
append(MS, [+ | NS], S).

write_tree([-, M, N], S) :-
write_tree(M, MS),
write_tree(N, NS),
( is_add(N) -> append(MS, [-, '(' | NS], Temp), append(Temp, ')', S)
; append(MS, [- | NS], S)).


write_tree([Op, M, N], S) :-
member(Op, [*, /]),
write_tree(M, MS),
write_tree(N, NS),
( is_add(M) -> append(['(' | MS], [')'], TempM)
; TempM = MS),
( is_add(N) -> append(['(' | NS], [')'], TempN)
; TempN = NS),
append(TempM, [Op | TempN], S).

is_add([Op, _, _]) :-
member(Op, [+, -]).

compute([Value], Value, [[_R-S1]], S) :-
write_tree(S1, S2),
with_output_to(atom(S), maplist(write, S2)).

compute(L, Value, CS, S) :-
select(M, L, L1),
select(N, L1, L2),
next_value(M, N, R, CS, Expr),
compute([R|L2], Value, Expr, S).

next_value(M, N, R, CS,[[R - [+, M1, N1]] | CS2]) :-
R is M+N,
( member([M-ExprM], CS) -> select([M-ExprM], CS, CS1), M1 = ExprM
; M1 = [M], CS1 = CS
),
( member([N-ExprN], CS1) -> select([N-ExprN], CS1, CS2), N1 = ExprN
; N1 = [N], CS2 = CS1
).

next_value(M, N, R, CS,[[R - [-, M1, N1]] | CS2]) :-
R is M-N,
( member([M-ExprM], CS) -> select([M-ExprM], CS, CS1), M1 = ExprM
; M1 = [M], CS1 = CS
),
( member([N-ExprN], CS1) -> select([N-ExprN], CS1, CS2), N1 = ExprN
; N1 = [N], CS2 = CS1
).

next_value(M, N, R, CS,[[R - [*, M1, N1]] | CS2]) :-
R is M*N,
( member([M-ExprM], CS) -> select([M-ExprM], CS, CS1), M1 = ExprM
; M1 = [M], CS1 = CS
),
( member([N-ExprN], CS1) -> select([N-ExprN], CS1, CS2), N1 = ExprN
; N1 = [N], CS2 = CS1
).

next_value(M, N, R, CS,[[R - [/, M1, N1]] | CS2]) :-
N \= 0,
R is rdiv(M,N),
( member([M-ExprM], CS) -> select([M-ExprM], CS, CS1), M1 = ExprM
; M1 = [M], CS1 = CS
),
( member([N-ExprN], CS1) -> select([N-ExprN], CS1, CS2), N1 = ExprN
; N1 = [N], CS2 = CS1
).

my_write(V) :-
format('~w ', [V]).</lang>
Example of output :
<pre>?- play24(4,9, 24).
6 2 3 4 : (6-2+4)*3
true ;
6 2 3 4 : 3*(6-2+4)
true ;
6 2 3 4 : (6-2+4)*3
true ;
6 2 3 4 : 3*(6-2+4)
true ;
6 2 3 4 : (6*2-4)*3
true ;
6 2 3 4 : 3*(6*2-4)
true ;
6 2 3 4 : 3*4+6*2
true ;
6 2 3 4 : 3*4+6*2
true ;
6 2 3 4 : 4*3+6*2
true ;
6 2 3 4 : 4*3+6*2
true ;
6 2 3 4 : (6/2+3)*4
true ;
6 2 3 4 : 4*(6/2+3)
true ;
6 2 3 4 : (6/2+3)*4
true ;
6 2 3 4 : 4*(6/2+3)
true ;
6 2 3 4 : (6-3)*2*4
true ;
6 2 3 4 : 4*(6-3)*2
true ;
6 2 3 4 : (6-3)*4*2
...

?- play24(7,99, 1).
66 40 2 76 95 59 12 : (66+40)/2-76+95-59-12
true ;
66 40 2 76 95 59 12 : (66+40)/2-76+95-12-59
true ;
66 40 2 76 95 59 12 : (66+40)/2-76-59+95-12
true ;
66 40 2 76 95 59 12 : (66+40)/2-76-59-12+95
true ;
66 40 2 76 95 59 12 : 95+(66+40)/2-76-59-12
true ;
66 40 2 76 95 59 12 : 95+(66+40)/2-76-59-12
true ;
66 40 2 76 95 59 12 : 95-12+(66+40)/2-76-59
true ;
66 40 2 76 95 59 12 : (66+40)/2-76-59+95-12
....
</pre>
=={{header|Python}}==
=={{header|Python}}==
The function is called '''solve''', and is integrated into the game player.
The function is called '''solve''', and is integrated into the game player.