2012-04-18 2 views
0

입력 스도쿠 보드가 인지 여부를 확인하는 간단한 프로그램을 작성하려고합니다. 현재이 올바르지 않습니다. 즉 행, 열 또는 '상자'에 두 개의 동일한 숫자가 있습니다. 행과 열 부분에 문제가 발생하지 않았습니다. 다음 코드를 사용하여 수행하는 상당히 간단한 작업입니다. '0'은 채워지지 않은 사각형을 나타냅니다.행에서 스도쿠 '박스'생성 - 프롤로그

그러나 KxK '상자'(K는 행 길이의 제곱근)를 나타내는 목록을 생성하는 방법에 대해서는 분명하지 않습니다. 나는 K의 가치를 얻었고, 행 1 (K * K)에 도달 할 때까지 행 1을 K 개의 하위 목록으로 분할하고 행 2의 K 하위 목록을 행 1의 하위 목록 끝에 추가하는 선을 따라 뭔가를하고 싶습니다.

불행히도, 어떻게 이런 일이 일어나게 될지 잘 모르겠습니다. BIP를 사용하면 목록을 가져 와서 X로 나눠서 각 Y 길이를 나열하는 선을 따라 무언가를 할 수 있습니까?

그렇지 않으면 아이디어가 있습니까? 내가 작은하지만 dowhile 루프에 대해 알고, 그들은 여기에 구현할 수있을 것 같아요,하지만 난 정말 그 중 하나를 어떻게 확신 할 수 없어? 도움을 많이 주셔서 감사합니다!

답변

1

인덱스 연산 및 루프를 사용할 수있는 간단하지 효율적인 방법 : 라이브러리의 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|...], [...|...]]. 
+0

대단히 감사합니다! 당신이 아마도 좀 더 잘 어울리는 것을 이해하는데 도움이된다면 궁금합니다. findall 내에서 중첩 된 betweens는 나에게 약간의 혼란을주고있는 것처럼 보인다! 그러나 Bs는 '블록'목록을 포함하는 목록이어야합니다 (뭔가 빠졌을 수도 있습니다). 그러나 항상 [[], [], [], []]로 끝나는 것 같습니다. . 어떤 생각이 거기에서 진행되고 있을지 모릅니다. 도움에 다시 한번 감사드립니다 - 정말 고맙습니다! – user1257768

+0

테스트 케이스를 추가했습니다. 편집을 참조하십시오. – CapelliC