Prolog中的谜语

时间:2012-03-31 11:11:10

标签: prolog puzzle

首先,我没有这个谜语的真实名称,它简直就是“ABC”。

一开始他们给我一块板子(nxm)和n,m =(1,10)和一个字母,例如C,所以我可以在ma解决方案中使用从A到C的字母。
然后我以形式(i,j,k)得到一些三分,i< = n,j< = m并且k属于(A,C)。

例如,它的开头看起来像这样:
Example board

对于每个空盒子,我必须以这样的方式键入字母A,B,C,当我完成输入时,它们必须满足以下条件:

  • 如果连续(列)中有不同的字母,则每个字母出现在此行(列)中的次数相同
  • 至少在一行(列)中所有字母都相同。

你知道如何解决这种谜语吗? 也许这个谜题有自己的名字,我可以读到它的某个地方?

修改 我必须从文件中读取的所有数据。这个文件看起来像这样:

  

4。   4。   'C'。   [(3,1,'B'),(4,1,'A'),(1,2,'B'),(4,2,'C'),(1,3,'C') ,(2,4,'A')]。

小纠正:只有一行或者列中所有字母都相同,而不是两者都有。 我的例子的解决方案是:

B A B A
B C B C
C C C C
C A C A

2 个答案:

答案 0 :(得分:1)

我认为@KarolyHorvath希望你分享的是如何在Prolog中代表董事会,以及你试图为自己解决这个问题的任何想法。接下来我将使用列表表示列表,内部列表是行及其项目符号或原子(单个小写字母,以保持简单)。

问题在某种意义上是拉丁方块的概括,它要求每一行和每一列中的每个符号中只有一个符号。使用新行和列包含一个拉丁方,其中只包含一些新符号,而不是在拉丁方中显示,并且您有一个解决方案可以满足您的问题要求。

也就是说,您的问题涉及部分完成的矩形板,不一定是正方形,符号频率可能因行与列而异。

对于像Example Board中所示的小型电路板,3x3阵列,蛮力方法很诱人。但是,有一些简单的代码可以使搜索更有效。

某些行和某些列必须是“常量”,即它们必须只包含一个字母。我想我会把它作为搜索树中最重要的选择,即选择一个可以是单个字母的行和列。请注意,由于每一行都与每列相交,因此我们将对该行和列使用相同的字母。

但在开始搜索解决方案之前,您需要输入代表电路板的数据及其“给定”条目。使用您自己对此的判断,但对于合理大小的板,您可以通过要求用户输入行数和列数,然后逐行提示它们来获取。

请记住,Prolog术语读者希望输入被句点终止。所以输入可能会像这样:

Enter a list of all letters:  [a,b,c].
How many rows?  4.
How many cols?  4.
Enter a row as a list:  [_,_,b,a].
Enter a row as a list:  [b,_,_,c].
Enter a row as a list:  [c,_,_,_].
Enter a row as a list:  [_,a,_,_].

下划线在输入时充当匿名变量,并将表示该板的相应列表条目列表保留为自由变量。

您可以使用以下代码表示程序中所有字母的列表:

Symbols = [a,b,c]

以及包含列表列表的电路板:

Board = [[A1,A2,b,a],[b,B2,B3,c],[c,C2,C3,C4],[D1,a,D3,D4]]

在特定示例中,只有一种方法可以将所有行和列设置为相同的字母,并且通过将第二列和最后一行都设置为全部a:

Board = [[A1,a,b,a],[b,a,B3,c],[c,a,C3,C4],[a,a,a,a]]

但现在我们发现寻找解决方案的过程陷入了困境。第二行有三个字母,但在长度为四的行中,三个字母不可能出现相同的次数。这个例子没有解决方案。

然而,“无解决方案”的结果非常有效。

希望这能为您提供有关如何在Prolog中编写常规求解过程的一些想法。

答案 1 :(得分:0)

您描述的问题可以看作是一种限制字母的限制问题。你的变量代表了棋盘上的位置,所以你将拥有n * m的这些。每个变量的范围超过可能值的有限域,由用户提供的字母表示。最后,用户输入的三元组和解决方案要满足的条件是约束条件。

为了在有限域上实现约束编程,可以使用不同的工具和库,例如,SWI-Prolog具有clpfd库。