How To Solve This Arithmetic Expression Puzzle In Prolog?
I have a programming problem (https://blog.svpino.com/2015/05/08/solution-to-problem-5-and-some-other-thoughts-about-this-type-of-questions): Write a program that outputs all pos
Solution 1:
the counterpart to Python eval could be implemented with read_term/3
and is/2
, or
give_100(A) :-
generate(1, S),
atomic_list_concat(S, A),
read_term_from_atom(A, T, []),
T =:= 100.
generate(9, [9]).
generate(N, [N|Ns]) :-
N < 9, sep(N, Ns).
sep(N, L) :-
( L = [+|Ns] ; L = [-|Ns] ; L = Ns ),
M is N+1,
generate(M, Ns).
Sample query:
?- give_100(X).
X = '1+2+3-4+5+6+78+9' ;
X = '1+2+34-5+67-8+9' ;
X = '1+23-4+5+6+78-9' ;
X = '1+23-4+56+7+8+9' ;
X = '12+3+4+5-6-7+89' ;
X = '12+3-4+5+67+8+9' ;
X = '12-3-4+5-6+7+89' ;
X = '123+4-5+67-89' ;
X = '123+45-67+8-9' ;
X = '123-4-5-6-7+8-9' ;
X = '123-45-67+89' ;
false.
Solution 2:
Using dcg, we first define nonterminalsep//0
:
sep -->"+" | "-" | "".
Then, we run the following query (using phrase/2
, sep//0
, read_from_codes/2
, and (=:=)/2
):
?- set_prolog_flag(double_quotes,chars).
true.
?- phrase(("1",sep,"2",sep,"3",sep,"4",sep,"5",sep,"6",sep,"7",sep,"8",sep,"9"),Cs),
read_from_codes(Cs,Expr),
Expr =:= 100.
Cs = [1,+,2,+,3,-,4,+,5,+,6,+,7,8,+,9], Expr = 1+2+3-4+5+6+78+9
; Cs = [1,+,2,+,3,4,-,5,+,6,7,-,8,+,9], Expr = 1+2+34-5+67-8+9
; Cs = [1,+,2,3,-,4,+,5,+,6,+,7,8,-,9], Expr = 1+23-4+5+6+78-9
; Cs = [1,+,2,3,-,4,+,5,6,+,7,+,8,+,9], Expr = 1+23-4+56+7+8+9
; Cs = [1,2,+,3,+,4,+,5,-,6,-,7,+,8,9], Expr = 12+3+4+5-6-7+89
; Cs = [1,2,+,3,-,4,+,5,+,6,7,+,8,+,9], Expr = 12+3-4+5+67+8+9
; Cs = [1,2,-,3,-,4,+,5,-,6,+,7,+,8,9], Expr = 12-3-4+5-6+7+89
; Cs = [1,2,3,+,4,-,5,+,6,7,-,8,9], Expr = 123+4-5+67-89
; Cs = [1,2,3,+,4,5,-,6,7,+,8,-,9], Expr = 123+45-67+8-9
; Cs = [1,2,3,-,4,-,5,-,6,-,7,+,8,-,9], Expr = 123-4-5-6-7+8-9
; Cs = [1,2,3,-,4,5,-,6,7,+,8,9], Expr = 123-45-67+89
; false.
Solution 3:
Quite the same as CapelliC's solution, but works with SWI-Prolog and module lambda:
:- use_module(library(lambda)).
sum_100(Atom) :-
L = [1,2,3,4,5,6,7,8,9],
O = [_A,_B,_C,_D,_E,_F,_G,_H,' '],
maplist(\X^member(X, [+,-,' ']), O),
foldl(\X^Y^Z^T^(Y = ' '
-> append(Z,[X], T)
; append(Z,[X,Y], T)), L, O, [], Expr),
atomic_list_concat(Expr, Atom),
term_to_atom(Term, Atom),
Term =:= 100.
Sample query:
?- sum_100(X).
X = '1+2+3-4+5+6+78+9' ;
X = '1+2+34-5+67-8+9' ;
X = '1+23-4+5+6+78-9' ;
X = '1+23-4+56+7+8+9' ;
X = '12+3+4+5-6-7+89' ;
X = '12+3-4+5+67+8+9' ;
X = '12-3-4+5-6+7+89' ;
X = '123+4-5+67-89' ;
X = '123+45-67+8-9' ;
X = '123-4-5-6-7+8-9' ;
X = '123-45-67+89' ;
false.
Post a Comment for "How To Solve This Arithmetic Expression Puzzle In Prolog?"