斑马拼图 - 谁住在哪一层?

Posted

技术标签:

【中文标题】斑马拼图 - 谁住在哪一层?【英文标题】:Zebra puzzle - who lives on which floor? 【发布时间】:2019-12-10 11:49:38 【问题描述】:

我有一个与这里描述的非常相似的斑马/爱因斯坦类型 Prolog 谜题:

A "Building" Riddle in Prolog.

谜底是:

有两栋楼,每栋都有树屋(每层一套):一套3房,一套4房,一套5房。

Dana、Joni 和 Noah 住​​在 1 号楼。Ron、Gale 和 Aron 住在 2 号楼。

Joni 的公寓比 Dana 和 Noah 的要高。这意味着他住在 1 号楼的三楼。诺亚和盖尔住在同一层(在不同的建筑物中)。 Ron 比 Aron 多一个房间。罗恩住在盖尔楼上。 2号楼最高的公寓是5房公寓。

我需要找出每个人住在哪一层。

这是代码。

solve([dana,building1,F1,R1],
      [noah,building1,F2,R2],
      [joni,building1,F3,R3],
      [gale,building2,F4,R4],
      [ron, building2,F5,R5],
      [aron,building2,F6,R6]) :-
   assign([1,2,3],[F1,F2,F3]),
   assign([1,2,3],[F4,F5,F6]),
   assign([3,4,5],[R1,R2,R3]),
   assign([3,4,5],[R4,R5,R6]),
   F3 > F2,
   F3 > F1,
   F2 =:= F4,
   R5 =:= R6-1,
   F5 =:= F4+1,
   (  F4 =:= 3, R4 =:= 5
   ;  F5 =:= 3, R5 =:= 5
   ;  F6 =:= 3, R6 =:= 5
   ).

assign(_,[]).
assign(Digs,[D|Vars]):-
   del(D,Digs,Digs1),
   assign(Digs1,Vars).

del(X,L,L1) :-
   remove(X,L,L1).

remove([],X,[]) :- !. 
remove([X|T],X,L1) :- !, remove(T,X,L1).   
remove([H|T],X,[H|L1]) :- remove(T,X,L1).

我不明白在以下解决方案中使用哪个查询?当我尝试从原始帖子中查询时,

solve([dana,building1,F1,R1],[noah,building1,F2,R2],[joni,building1,F3,R3],
      [gale,building2,F4,R4],[ron, building2,F5,R5],[aron,building2,F6,R6]).

它说

Type error: `evaluable' expected, found `[]' (an empty_list)
In:
   [2] []>[]
   [1] solve([dana,building1|...],[noah,building1|...],[joni,building1|...],
             [gale,building2|...],[ron, building2|...],[aron,building2|...]) 
at  line 1

对此的正确查询是什么?

谢谢。

【问题讨论】:

solve 调用assign,后者调用del,后者调用remove,此代码中未定义。你打电话给solve是正确的。您将需要寻找remove 的定义,可能在您获得此代码的地方附近。或者它期望它是一个内置的,而你正在运行与作者不同的 Prolog 版本。 SWI's select/3 很适合这个问题。 @PaulBrown 我添加了 remove 但现在由于另一个原因它失败了。你能帮忙吗?谢谢。 顺便说一句,如果您现在有一个工作代码,您可以将其发布到CodeReview 并要求在那里对其进行审查,以获得有关代码的一些反馈,是否可以进行不同的编码 / "更好”/更简单等(提示:可以)。请务必查看该网站的指南,询问您是否决定这样做。 【参考方案1】:

查询对于给定的代码是正确的。

代码包含错误。

del(X,L,L1) :-
   remove(X,L,L1).   % WRONG

您需要更改对remove/3 的调用中的参数顺序,以对应它们在remove/3 的定义中的使用。

你可以通过测试来发现它。只需在提示符处尝试查询assign([1,2,3],Floors),您就会发现它是否按预期工作

或者del(D,[1,2,3],Digs1),遵循assign/2的定义,

assign([1,2,3],[D|Vars]):-
   del(D,[1,2,3],Digs1),
   ..... .

或者remove(D,[1,2,3],Digs1),遵循del/3的定义,

del(D,[1,2,3],Digs1) :-
   remove(D,[1,2,3],Digs1).

看定义

remove([],   X,[]    ) :- !. 
remove([X|T],X,L1    ) :- !, remove(T,X,L1).
remove([H|T],X,[H|L1]) :- remove(T,X,L1).

知道我们对 D 的预期含义是从 ​​[1,2,3] 中保留一个 数字

(其余部分故意留空)

【讨论】:

以上是关于斑马拼图 - 谁住在哪一层?的主要内容,如果未能解决你的问题,请参考以下文章

Prolog 逻辑拼图不起作用?

拼图游戏 v1.1

拼图数量增加,拼图游戏中拼图大小增加

积木拼图游戏-儿童游戏免费拼图3-6岁

android滑动拼图验证码控件

HTML5人物拼图游戏