簡単、効率的ではない方法は、指数演算を使用して、ループができた:ライブラリのdocumentationで
...
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).
(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|...], [...|...]].
はどうもありがとうございました!しかし、ここで何が起こっているのか理解してもらえると嬉しいですか? findall内にネストされた仲間は私に混乱を与えているようです!しかし、それはいつも[[]、[]、[]、[]]に終わっているように思えます。 。何が起こっているのでしょうか?もう一度助けてくれてありがとう - 本当に感謝しています! – user1257768
私はテストケースを追加しました:編集を見てください – CapelliC