繁体   English   中英

使用谓词解决 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也不工作。在此处输入图像描述

下面是基于 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).

首先在修复ins / labeling问题之前:您的代码 #1 和 #3 存在问题。 在代码 #1 中,您 state 所有变量都需要具有不同的值。 这不会提供有效的解决方案。 在代码#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).

这是(唯一的)output for ?- kakuro(L). :

[9, 8, 7, 8, 2, 1, 9, 5, 8, 7, 2, 5]

首先,您需要运行ins/2谓词。 这应该适用于 SWI prolog。其次,您知道如何处理labeling/2谓词。 这一个将从他们的域(通过ins/2给出)给定的值设置到条目。 在 SWI Prolog 中,第一个属性是一个选项列表,不用担心。 标记变量,您可以“测试”它们并对它们施加约束。 您可以在开始时为所有变量做一次标记,但这很慢,因为您的所有进度都丢失了。 所以我建议在word/2谓词中这样做。 如果出现死胡同,回溯会回到word/2谓词而不是kakuro/1谓词的开头。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM