使用谓词在 prolog 中解决 kakuro
solving kakuro in prolog using predicate
我要谓词解数郎
我的数郎是这个
我必须使用单词 solve (solve/1) 为游戏 kakuro 创建一个谓词。我尝试了 3-4 个代码,但它们都有错误。变量必须在 1-9 之间(一个值在 1-9 之间)并且所有变量在一行和一列中必须不同(24=A+B+C 而不是 24=A+A+C)。
第一个密码是:
:- use_module(library(clpfd)).
solve(L):-
L= [A,B,C,E,F,G,J,K,L,N,O,P],
all_different(L),
L ins 1..9,
A #= 24-B-C,
B #= 26-F-J-N,
C #= 15-G-K-O,
E #= 11-F-G,
E #= 17-A,
J #= 22-K-L,
N #= 14-O-P,
L #= 13-P.
第二个代码:
:- use_module(library(clpfd)).
sum_list([],0).
sum_list([Head|Tail], Sum):-sum_list(Tail, Sum1),Sum is Head+Sum1.
go:-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
labeling(Vars),
writeln(Vars).
word(L,Sum):-
sum_list(L,X),
X=:=Sum,
all_different(L).
第三个密码:
:- use_module(library(clpfd)).
kakuro(L):-
L = [A,B,C,E,F,G,J,K,L,N,O,P],
L ins 1..9,
Z1 = [A,B,C],
all_different(Z1),
A =:= 24-B-C,
Z2 = [B,F,J,N],
all_different(Z2),
B =:=26-F-J-N,
Z3 = [C,G,K,O],
all_different(Z3),
C =:= 15-G-K-O,
Z4 = [E,F,G],
all_different(Z4),
E =:= 11-F-G,
Z5 = [A,E],
all_different(Z5),
E =:= 17-A,
Z6 = [J,K,L],
all_different(Z6),
J =:=22-K-L,
A1 = [N,O,P],
all_different(A1),
N =:= 14-O-P,
A2 = [L,P],
all_different(A2),
L =:=13-P,
labeling([], L).
另外,如何开始求解过程?会像:?-solve(L).
?? L ins 1..9
也不起作用。
首先在修复 ins
/labeling
问题之前:您的代码 #1 和 #3 存在问题。在代码 #1 中,您声明所有变量都需要具有不同的值。这不会提供有效的解决方案。在代码 #1 和 #3 中,您使用变量 L
一次作为变量的容器,一次作为一个元素。
我已经用 Swish 测试了我的代码。这是代码:
:- use_module(library(clpfd)).
sum_list([],0).
sum_list([Head|Tail], Sum):-
sum_list(Tail, Sum1),
Sum is Head+Sum1.
kakuro(Vars):-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
writeln(Vars).
word(L,Sum):-
labeling([],L),
all_different(L),
sum_list(L,Sum).
这是 ?- kakuro(L).
的(唯一)输出:
[9, 8, 7, 8, 2, 1, 9, 5, 8, 7, 2, 5]
首先你需要有ins/2
谓词运行。这应该与 SWI prolog 一起使用。其次,您知道如何处理 labeling/2
谓词。这一个将从他们的域(通过 ins/2
给出)给定的值设置到条目。在 SWI Prolog 中,第一个属性是选项列表,无需担心。 AFTER 标记您的变量后,您可以“测试”它们并对其施加约束。您可以在开始时为所有变量做一次标记,但这很慢,因为您的所有进度都丢失了。所以我建议在 word/2
谓词中进行。如果出现死胡同,回溯会回到 word/2
谓词,而不是 kakuro/1
谓词的开头。
下面是基于DuDa的解决方案,但是使用了sum/3
约束,延迟标注到最后。这使得解决方案更高效、更具声明性。
:- use_module(library(clpfd)).
kakuro(Vars):-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
labeling([],Vars).
word(L,Sum):-
all_different(L),
sum(L,#=,Sum).
我要谓词解数郎
我的数郎是这个
我必须使用单词 solve (solve/1) 为游戏 kakuro 创建一个谓词。我尝试了 3-4 个代码,但它们都有错误。变量必须在 1-9 之间(一个值在 1-9 之间)并且所有变量在一行和一列中必须不同(24=A+B+C 而不是 24=A+A+C)。
第一个密码是:
:- use_module(library(clpfd)).
solve(L):-
L= [A,B,C,E,F,G,J,K,L,N,O,P],
all_different(L),
L ins 1..9,
A #= 24-B-C,
B #= 26-F-J-N,
C #= 15-G-K-O,
E #= 11-F-G,
E #= 17-A,
J #= 22-K-L,
N #= 14-O-P,
L #= 13-P.
第二个代码:
:- use_module(library(clpfd)).
sum_list([],0).
sum_list([Head|Tail], Sum):-sum_list(Tail, Sum1),Sum is Head+Sum1.
go:-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
labeling(Vars),
writeln(Vars).
word(L,Sum):-
sum_list(L,X),
X=:=Sum,
all_different(L).
第三个密码:
:- use_module(library(clpfd)).
kakuro(L):-
L = [A,B,C,E,F,G,J,K,L,N,O,P],
L ins 1..9,
Z1 = [A,B,C],
all_different(Z1),
A =:= 24-B-C,
Z2 = [B,F,J,N],
all_different(Z2),
B =:=26-F-J-N,
Z3 = [C,G,K,O],
all_different(Z3),
C =:= 15-G-K-O,
Z4 = [E,F,G],
all_different(Z4),
E =:= 11-F-G,
Z5 = [A,E],
all_different(Z5),
E =:= 17-A,
Z6 = [J,K,L],
all_different(Z6),
J =:=22-K-L,
A1 = [N,O,P],
all_different(A1),
N =:= 14-O-P,
A2 = [L,P],
all_different(A2),
L =:=13-P,
labeling([], L).
另外,如何开始求解过程?会像:?-solve(L).
?? L ins 1..9
也不起作用。
首先在修复 ins
/labeling
问题之前:您的代码 #1 和 #3 存在问题。在代码 #1 中,您声明所有变量都需要具有不同的值。这不会提供有效的解决方案。在代码 #1 和 #3 中,您使用变量 L
一次作为变量的容器,一次作为一个元素。
我已经用 Swish 测试了我的代码。这是代码:
:- use_module(library(clpfd)).
sum_list([],0).
sum_list([Head|Tail], Sum):-
sum_list(Tail, Sum1),
Sum is Head+Sum1.
kakuro(Vars):-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
writeln(Vars).
word(L,Sum):-
labeling([],L),
all_different(L),
sum_list(L,Sum).
这是 ?- kakuro(L).
的(唯一)输出:
[9, 8, 7, 8, 2, 1, 9, 5, 8, 7, 2, 5]
首先你需要有ins/2
谓词运行。这应该与 SWI prolog 一起使用。其次,您知道如何处理 labeling/2
谓词。这一个将从他们的域(通过 ins/2
给出)给定的值设置到条目。在 SWI Prolog 中,第一个属性是选项列表,无需担心。 AFTER 标记您的变量后,您可以“测试”它们并对其施加约束。您可以在开始时为所有变量做一次标记,但这很慢,因为您的所有进度都丢失了。所以我建议在 word/2
谓词中进行。如果出现死胡同,回溯会回到 word/2
谓词,而不是 kakuro/1
谓词的开头。
下面是基于DuDa的解决方案,但是使用了sum/3
约束,延迟标注到最后。这使得解决方案更高效、更具声明性。
:- use_module(library(clpfd)).
kakuro(Vars):-
Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
Vars ins 1..9,
word([A,B,C],24),
word([B,F,J,N],26),
word([C,G,K,O],15),
word([E,F,G],11),
word([A,E],17),
word([J,K,L],22),
word([N,O,P],14),
word([L,P],13),
labeling([],Vars).
word(L,Sum):-
all_different(L),
sum(L,#=,Sum).