幻方序言
Magic square prolog
我有这段代码,我想重构一个部分以提高效率。
num(1).
num(2).
num(3).
num(4).
num(5).
num(6).
num(7).
num(8).
num(9).
nums(A,B,C,D,E,F,G,H,I):-
num(A),num(B),num(C),
num(D),num(E),num(F),
num(G),num(H),num(I),
A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I,
B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I,
C\==D,C\==E,C\==F,C\==G,C\==H,C\==I,
D\==E,D\==F,D\==G,D\==H,D\==I,
E\==F,E\==G,E\==H,E\==I,
F\==G,F\==H,F\==I,
G\==H,G\==I,
H\==I.
square(A,B,C,D,E,F,G,H,I):-
nums(A,B,C,D,E,F,G,H,I),
S1 is A + B + C,
S2 is D + E + F,
S3 is G + H + I,
S4 is A + D + G,
S5 is B + E + H,
S6 is C + F + I,
S7 is A + E + I,
S8 is G + E + C,
S1==S2,S2==S3,S3==S4,S4==S5,S5==S6,S6==S7,S7==S8.
solution([A,B,C,D,E,F,G,H,I]):-square(A,B,C,D,E,F,G,H,I).
我想减少的部分是这个,我不知道如何使用一个函数,我需要避免在我使用大量代码的地方做这样的事情,而是创建一个我可以解决的函数几行
A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I,
B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I,
C\==D,C\==E,C\==F,C\==G,C\==H,C\==I,
D\==E,D\==F,D\==G,D\==H,D\==I,
E\==F,E\==G,E\==H,E\==I,
F\==G,F\==H,F\==I,
G\==H,G\==I,
H\==I.
我建议你使用CLP(FD)来解决这类问题:
fd_square(Sol, Sum):-
Sol=[A,B,C,D,E,F,G,H,I],
Sol ins 1..9,
all_distinct(Sol),
maplist(#=(Sum),
[
A + B + C,
D + E + F,
G + H + I,
A + D + G,
B + E + H,
C + F + I,
A + E + I,
G + E + C
]).
样本运行:
?- fd_square(Sol, Sum), label(Sol).
Sol = [2, 7, 6, 9, 5, 1, 4, 3, 8],
Sum = 15 ;
Sol = [2, 9, 4, 7, 5, 3, 6, 1, 8],
Sum = 15 ;
Sol = [4, 3, 8, 9, 5, 1, 2, 7, 6],
Sum = 15 ;
Sol = [4, 9, 2, 3, 5, 7, 8, 1, 6],
Sum = 15 ;
Sol = [6, 1, 8, 7, 5, 3, 2, 9, 4],
Sum = 15 ;
Sol = [6, 7, 2, 1, 5, 9, 8, 3, 4],
Sum = 15 ;
Sol = [8, 1, 6, 3, 5, 7, 4, 9, 2],
Sum = 15 ;
Sol = [8, 3, 4, 1, 5, 9, 6, 7, 2],
Sum = 15 ;
false.
我有这段代码,我想重构一个部分以提高效率。
num(1).
num(2).
num(3).
num(4).
num(5).
num(6).
num(7).
num(8).
num(9).
nums(A,B,C,D,E,F,G,H,I):-
num(A),num(B),num(C),
num(D),num(E),num(F),
num(G),num(H),num(I),
A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I,
B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I,
C\==D,C\==E,C\==F,C\==G,C\==H,C\==I,
D\==E,D\==F,D\==G,D\==H,D\==I,
E\==F,E\==G,E\==H,E\==I,
F\==G,F\==H,F\==I,
G\==H,G\==I,
H\==I.
square(A,B,C,D,E,F,G,H,I):-
nums(A,B,C,D,E,F,G,H,I),
S1 is A + B + C,
S2 is D + E + F,
S3 is G + H + I,
S4 is A + D + G,
S5 is B + E + H,
S6 is C + F + I,
S7 is A + E + I,
S8 is G + E + C,
S1==S2,S2==S3,S3==S4,S4==S5,S5==S6,S6==S7,S7==S8.
solution([A,B,C,D,E,F,G,H,I]):-square(A,B,C,D,E,F,G,H,I).
我想减少的部分是这个,我不知道如何使用一个函数,我需要避免在我使用大量代码的地方做这样的事情,而是创建一个我可以解决的函数几行
A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I,
B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I,
C\==D,C\==E,C\==F,C\==G,C\==H,C\==I,
D\==E,D\==F,D\==G,D\==H,D\==I,
E\==F,E\==G,E\==H,E\==I,
F\==G,F\==H,F\==I,
G\==H,G\==I,
H\==I.
我建议你使用CLP(FD)来解决这类问题:
fd_square(Sol, Sum):-
Sol=[A,B,C,D,E,F,G,H,I],
Sol ins 1..9,
all_distinct(Sol),
maplist(#=(Sum),
[
A + B + C,
D + E + F,
G + H + I,
A + D + G,
B + E + H,
C + F + I,
A + E + I,
G + E + C
]).
样本运行:
?- fd_square(Sol, Sum), label(Sol).
Sol = [2, 7, 6, 9, 5, 1, 4, 3, 8],
Sum = 15 ;
Sol = [2, 9, 4, 7, 5, 3, 6, 1, 8],
Sum = 15 ;
Sol = [4, 3, 8, 9, 5, 1, 2, 7, 6],
Sum = 15 ;
Sol = [4, 9, 2, 3, 5, 7, 8, 1, 6],
Sum = 15 ;
Sol = [6, 1, 8, 7, 5, 3, 2, 9, 4],
Sum = 15 ;
Sol = [6, 7, 2, 1, 5, 9, 8, 3, 4],
Sum = 15 ;
Sol = [8, 1, 6, 3, 5, 7, 4, 9, 2],
Sum = 15 ;
Sol = [8, 3, 4, 1, 5, 9, 6, 7, 2],
Sum = 15 ;
false.