学习序言,数独求解器
Learning Prolog, Sudoku Solver
我的问题是:
在学习 Prolog 时,我想制作一个 NxN 数独求解器。
这个求解器将得到像
这样的输入
[[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]]
其中一些可能是变量。求解器必须解决该数独问题。
问题要小得多:
firstElementsOf([],_).
firstElementsOf([[X|_]|Rest2],Y) :-
firstElementsOf(Rest2,Y2),
append([X],[Y2],NotFlat),
flatten(NotFlat,Y).
如果每一列都有不同的数字,这应该是检查的开始。 firstElementsOf
中的 Y
应该只包含给定行的第一个元素。在示例中:
[1,3,2,4]
遗憾的是,多亏了 append,它总是会在 Y
列表中添加另一个空的 space。
它给出:
[1,3,2,4,_1320]
问题 1:有没有办法摆脱那个 _1320
?
问题2:这样对吗?有没有办法用它来获取输入的第二个和第三个元素?
对于问题1:我想错误在
firstElementsOf([],_).
我觉得应该
firstElementsOf([],[]).
题外话:你确定不能把other从句简单写成下面这样吗?
firstElementsOf([[X|_]|Rest2],[X|Y]) :-
firstElementsOf(Rest2,Y).
对于问题 2:我提出一个更一般的谓词:以下 getPosList/3
支持 getPosElem/3
getPosElem([H | _], 1, H).
getPosElem([_ | T], Pos, H) :-
Pos > 1,
Pm1 is Pos - 1,
getPosElem(T, Pm1, H).
getPosList([], _, []).
getPosList([H | T], Pos, [E | L]) :-
getPosElem(H, Pos, E),
getPosList(T, Pos, L).
提取位置Pos
所有元素的列表,所以
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 1, L),
相当于firstElementOf([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], L)
提取[1, 3, 2, 4]
,
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 2, L),
提取[2, 4, 3, 1]
,
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 3, L),
摘录 [3, 1, 4, 2]
、
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 4, L),
提取[4, 2, 1, 3]
和
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 5, L),
或大于 5 的数字,return false
我的问题是: 在学习 Prolog 时,我想制作一个 NxN 数独求解器。 这个求解器将得到像
这样的输入 [[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]]
其中一些可能是变量。求解器必须解决该数独问题。 问题要小得多:
firstElementsOf([],_).
firstElementsOf([[X|_]|Rest2],Y) :-
firstElementsOf(Rest2,Y2),
append([X],[Y2],NotFlat),
flatten(NotFlat,Y).
如果每一列都有不同的数字,这应该是检查的开始。 firstElementsOf
中的 Y
应该只包含给定行的第一个元素。在示例中:
[1,3,2,4]
遗憾的是,多亏了 append,它总是会在 Y
列表中添加另一个空的 space。
它给出:
[1,3,2,4,_1320]
问题 1:有没有办法摆脱那个 _1320
?
问题2:这样对吗?有没有办法用它来获取输入的第二个和第三个元素?
对于问题1:我想错误在
firstElementsOf([],_).
我觉得应该
firstElementsOf([],[]).
题外话:你确定不能把other从句简单写成下面这样吗?
firstElementsOf([[X|_]|Rest2],[X|Y]) :-
firstElementsOf(Rest2,Y).
对于问题 2:我提出一个更一般的谓词:以下 getPosList/3
支持 getPosElem/3
getPosElem([H | _], 1, H).
getPosElem([_ | T], Pos, H) :-
Pos > 1,
Pm1 is Pos - 1,
getPosElem(T, Pm1, H).
getPosList([], _, []).
getPosList([H | T], Pos, [E | L]) :-
getPosElem(H, Pos, E),
getPosList(T, Pos, L).
提取位置Pos
所有元素的列表,所以
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 1, L),
相当于firstElementOf([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], L)
提取[1, 3, 2, 4]
,
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 2, L),
提取[2, 4, 3, 1]
,
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 3, L),
摘录 [3, 1, 4, 2]
、
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 4, L),
提取[4, 2, 1, 3]
和
getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 5, L),
或大于 5 的数字,return false