我正在尝试编写一个简单的程序,只检查输入数独板是否当前不正确;即它在行,列或“框”中有两个相同的数字。 我没有遇到任何关于行和列部分的麻烦 - 这是一个相当直接的任务,我用下面的代码完成(应该注意'0'代表一个尚未填充的正方形):
:- use_module(library(clpfd)).
%Takes a matrix, determines if any row has repeating numbers
check([H|T]):-
all_diff(H),
check(T).
check([]).
%takes a list, checks if it contains repetitions other than '0'.
all_diff([]).
all_diff([X|Xs]) :-
( X = 0 ->
all_diff(Xs)
;
\+memberchk(X, Xs),
all_diff(Xs)
).
consistent(Rows):-
check(Rows), %verify rows are free of repeats
transpose(Rows,Columns), %L1 represents columns
check(Columns), %verify all columns are free of repeats
[H|T] = Rows,
length(H,M),
K is integer(sqrt(M)). %this will give me dimensions of each box (KxK)
但是,我不太清楚如何生成代表KxK'框'的列表(其中K是行长度的平方根)。 我得到了K的值,我想我想按照将row1划分为K个子列表的方式做一些事情,然后将row2的K个子列表附加到row1的子列表的末尾,直到我到达行(K * K)。
不幸的是,我真的不确定如何实现这一目标?是否有一个我可以使用的BIP,它会按照列表并将其分成长度为Y的X列表来执行某些操作?
否则,任何想法?我知道 tiny 但关于dowhile循环,我想它们可以在这里实现,但我不确定我会怎么做? 非常感谢你的帮助!
答案 0 :(得分:1)
一种简单而无效的方法可以使用索引算法和循环:
...
Sq = 3,
findall(B, (between(1, Sq, R),
between(1, Sq, C),
block(M, Sq, R, C, B)), Bs).
cell(M, R,C, V) :-
nth1(R,M,Row), nth1(C,Row,V).
block(M, Sq, R,C, B) :-
findall(V, (between(1, Sq, X),
between(1, Sq, Y),
I is (R-1) * Sq + X,
J is (C-1) * Sq + Y,
cell(M, I, J, V)), B).
在documentation库(clpfd)中,有一种更有效的方法,仅限于已知的标准维度。您可以尝试概括该代码。
编辑这是我的测试用例:请注意矩阵是假的,只是让我们很容易理解块的位置。
q(Bs) :-
M = [[1,2,3,4,5,6,7,8,9],
[a,b,c,d,_,3,_,8,5],
[x,y,z,_,2,_,_,_,_],
[u,v,z,e,t,y,_,_,_],
[b,b,b,e,t,y,1,_,_],
[c,c,c,e,t,y,_,_,_],
[5,_,_,_,_,_,_,7,3],
[_,_,2,_,1,_,_,_,_],
[_,_,_,_,4,_,_,_,9]],
Sq = 3,
findall(B, (between(1, Sq, R),
between(1, Sq, C),
block(M, Sq, R, C, B)), Bs).
cell(M, R,C, V) :-
nth1(R,M,Row), nth1(C,Row,V).
block(M, Sq, R,C, B) :-
findall(V, (between(1, Sq, X),
between(1, Sq, Y),
I is (R-1) * Sq + X,
J is (C-1) * Sq + Y,
cell(M, I, J, V)), B).
并使用此命令进行测试:
?- q(Bs),maplist(writeln,Bs).
[1,2,3,a,b,c,x,y,z]
[4,5,6,d,_G928,3,_G934,2,_G940]
[7,8,9,_G895,8,5,_G904,_G907,_G910]
[u,v,z,b,b,b,c,c,c]
[e,t,y,e,t,y,e,t,y]
[_G796,_G799,_G802,1,_G808,_G811,_G814,_G817,_G820]
[5,_G769,_G772,_G775,_G778,2,_G784,_G787,_G790]
[_G736,_G739,_G742,_G745,1,_G751,_G754,4,_G760]
[_G706,7,3,_G715,_G718,_G721,_G724,_G727,9]
Bs = [[1, 2, 3, a, b, c, x, y|...], [4, 5, 6, d, _G928, 3, _G934|...], [7, 8, 9, _G895, 8, 5|...], [u, v, z, b, b|...], [e, t, y, e|...], [_G796, _G799, _G802|...], [5, _G769|...], [_G736|...], [...|...]].