【问题标题】:is prolog a good language to solve sudoku or minesweeper-like puzzleprolog 是解决数独或类似扫雷游戏的好语言吗
【发布时间】:2019-03-12 23:29:56
【问题描述】:

我意识到我写这个就像一个家庭作业问题,但那是因为它是我理解和尝试传递问题的最简单方法。这是我想为个人项目解决的问题。


我将卡片布置在网格中,我从一个简单的 2x2 网格案例开始,但希望最终能够外推到更大的 n×n 网格。

卡片全部正面朝下,卡片正面印有:

  1. 正非零整数,代表卡片的“分数”
  2. 或黑点。

给我每行得分总和、每行黑点个数、每列得分总和、每列黑点个数的信息。

所以第一行的总分必须为 1,并且恰好其中一张牌是黑点。

最右边一列的总分必须为 2,并且其中一张牌是黑点。

等等

当然我们可以看到上面的网格会“解决”到


现在我想创建一个函数来输入给定的信息并生成满足这些约束的卡片网格。

我想我可以在函数中使用类似元组的参数。

然后网格中的每个“单元格”或卡片本身就是一个元组,元组的第一个元素将是那里卡片的分数(如果是黑点则为 0),第二个元素将是如果卡片是黑点则为 1,否则为 0。

所以网格必须类似于那个^^

我可以通过求解这个方程组找出所有ab 变量是什么:

(也知道所有这些数字都是≥0的整数)。


我想用这个问题作为 prolog 中的一个学习练习,我认为这似乎是一个 Prolog 将优雅地解决的问题。

我做出了正确的决定还是 Prolog 不是一个好的选择?

我想知道如何在 Prolog 中实现它。

【问题讨论】:

标签: prolog sudoku


【解决方案1】:

Prolog 非常适合这类问题。看看 clp(fd),也就是有限域中的约束逻辑编程。

这个 sn-p 显示了如何在 SWI Prolog 中解决初始 2x2 示例的原始方法:

:- use_module(library(clpfd)).

 test(Vars) :-
    Vars = [TopLeft, TopRight, BottomLeft, BottomRight],
    global_cardinality([TopLeft, TopRight],       [0-1,1-_,2-_]), TopLeft + TopRight #= 1,
    global_cardinality([TopLeft, BottomLeft],     [0-1,1-_,2-_]), TopLeft + BottomLeft #= 1,
    global_cardinality([BottomLeft, BottomRight], [0-1,1-_,2-_]), BottomLeft + BottomRight #= 2,
    global_cardinality([TopRight, BottomRight],   [0-1,1-_,2-_]), TopRight + BottomRight #= 2,
    label(Vars).

查询:

?- test(Vars).
Vars = [1, 0, 0, 2].

您可以以此为起点进行概括。请注意,黑点表示为 0,因为 clp(fd) 只处理整数。

这里是文档:http://www.swi-prolog.org/man/clpfd.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2023-03-04
    • 2012-11-15
    • 2021-03-30
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多