91 lines
2.1 KiB
Prolog
91 lines
2.1 KiB
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]).
|