如何在prolog中获取块的所有元素?大小可以在我的代码中改变动态,因此块大小不同,4x4 = 4个元素,9x9 = 9个元素等。块被切割成正方形,因此在4x4中水平长度是圆形(sqrt(4))= 2和垂直块的长度是圆形(sqrt(4))= 2.和9x9 ... sqrt(9)..所以块的高度和宽度是3.我需要一个算法来使元素有效。
我的sudokulists以这种方式建立:
L = [ [4,3,1,2], [2,1,4,3], [3,4,2,1], [1,2,3,4] ],
这是一个列表,其中包含sudoku中的行列表。检查行和列是没有问题的, - > all_different检查行,转置整个List,all_different检查转置列表。
但是由于数独的动态大小,我无法编写块的修复代码。所以有人有任何想法?我考虑过flatten(L)并使用偏移来获得正确的块,但这样做似乎很难吗?
请帮助我!
答案 0 :(得分:2)
一个可能的解决方案如下(假设你有blocksize
x blocksize
块大小blocksize
x blocksize
- 在标准数独中所有数字相等,可以调整匹配其他布局)
a = [],...,[]
成为blocksize
存储桶的列表。blocksize
部分。a
blocksize
x blocksize
块在你的例子中:
L=[ [4,3,1,2], [2,1,4,3], [3,4,2,1], [1,2,3,4] ]
Partitions => [[4,3] [1,2] [2,1] [4,3] [3,4] [2,1] [1,2] [3,4]]
Bucketed => [[4,3] [2,1] [3,4] [1,2]] [[1,2] [4,3] [2,1] [3,4]]
Flattened => [4,3,2,1,3,4,1,2,1,2,4,3,2,1,3,4]
Partitioned => [4,3,2,1], [3,4,1,2], [1,2,4,3], [2,1,3,4]]
答案 1 :(得分:1)
这是一些简单的Prolog,用于在列表列表表示中转置矩阵。我们的想法是通过从每个现有行中拉出头来创建一个新的“第一行”,然后递归到“剩余”尾部列表中。
transpose([[ ]|_],[ ]) :- !.
transpose(A,[H|T]) :-
decap_List(A,H,B),
transpose(B,T).
decap_List([ ],[ ],[ ]).
decap_List([[H|T]|Rows],[H|Hs],[T|Ts]) :-
decap_List(Rows,Hs,Ts).
例如:
?- transpose([[1,2,3],[4,5,6],[7,8,9]],X).
X = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
但是请注意,对于大小为K²xK²的广义数独矩阵,在每个“框”中也有“所有不同”的条目,其大小为 KxK 平铺矩阵。使用与以前相同的设计,您还需要一个谓词将数独矩阵重新打包到“盒子”列表列表中。
要做到这一点,只需要一个进一步的谓词,将矩阵“分割”成每组 K 行。
part_K_rows([ ],_,[ ]) :- !.
part_K_rows(A,K,[H|T]) :-
get_K_rows(A,K,H,B),
part_K_rows(B,K,T).
get_K_rows(A,0,[ ],A) :- !.
get_K_rows([H|T],K,[H|Z],B),
J is K-1,
get_K_rows(T,J,Z,B).
将 part_K_rows / 3 应用于原始数独矩阵,然后转置每个生成的行分区并将 part_K_rows / 3 应用于每个分区将生成所需的列表“盒子”列表。