/* Crypt benchmark in Picat v3. From bench/crypt.pl (for Picat v3) https://github.com/SWI-Prolog/bench Changes: I had to rename odd -> oddx and even -> evenx since they are defined in Picat standard module. (Got a weird error: error(instantiation_error,mod/2) before renaming) This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. % import cp. main => go. go ?=> oddx(A), evenx(B), evenx(C), evenx(E), mult([C,B,A], E, [I,H,G,F|X]), lefteven(F), oddx(G), evenx(H), evenx(I), zero(X), lefteven(D), mult([C,B,A], D, [L,K,J|Y]), lefteven(J), oddx(K), evenx(L), zero(Y), sum([I,H,G,F], [0,L,K,J], [P,O,N,M|Z]), oddx(M), oddx(N), evenx(O), evenx(P), zero(Z), print(' '), print(A), print(B), print(C), nl, print(' '), print(D), print(E), nl, print(F), print(G), print(H), print(I), nl, print(J), print(K), print(L), nl, print(M), print(N), print(O), print(P), nl, fail, nl. go => true. % Cryptomultiplication: % Find the unique answer to: % OEE % EE % --- % EOEE % EOE % ---- % OOEE % % where E=even, O=odd. % This program generalizes easily to any such problem. % Written by Peter Van Roy top:- oddx(A), evenx(B), evenx(C), evenx(E), mult([C,B,A], E, [I,H,G,F|X]), lefteven(F), oddx(G), evenx(H), evenx(I), zero(X), lefteven(D), mult([C,B,A], D, [L,K,J|Y]), lefteven(J), oddx(K), evenx(L), zero(Y), sum([I,H,G,F], [0,L,K,J], [P,O,N,M|Z]), oddx(M), oddx(N), evenx(O), evenx(P), zero(Z), % print(' '), print(A), print(B), print(C), nl, % print(' '), print(D), print(E), nl, % print(F), print(G), print(H), print(I), nl, % print(J), print(K), print(L), nl, % print(M), print(N), print(O), print(P), % nl, fail, nl. top. % Addition of two numbers sum(AL, BL, CL) :- sum(AL, BL, 0, CL). sum([A|AL], [B|BL], Carry, [C|CL]) :- !, X is (A+B+Carry), C is X mod 10, NewCarry is X // 10, sum(AL, BL, NewCarry, CL). sum([], BL, 0, BL) :- !. sum(AL, [], 0, AL) :- !. sum([], [B|BL], Carry, [C|CL]) :- !, X is B+Carry, NewCarry is X // 10, C is X mod 10, sum([], BL, NewCarry, CL). sum([A|AL], [], Carry, [C|CL]) :- !, X is A+Carry, NewCarry is X // 10, C is X mod 10, sum([], AL, NewCarry, CL). sum([], [], Carry, [Carry]). % Multiplication mult(AL, D, BL) :- mult(AL, D, 0, BL). mult([A|AL], D, Carry, [B|BL] ) :- X is A*D+Carry, B is X mod 10, NewCarry is X // 10, mult(AL, D, NewCarry, BL). mult([], _, Carry, [C,Cend]) :- C is Carry mod 10, Cend is Carry // 10. zero([]). zero([0|L]) :- zero(L). oddx(1). oddx(3). oddx(5). oddx(7). oddx(9). evenx(0). evenx(2). evenx(4). evenx(6). evenx(8). lefteven(2). lefteven(4). lefteven(6). lefteven(8).