비 추측 스도쿠 솔버 구현


27

가장 짧은 스도쿠 솔버를 구현하십시오.

스도쿠 퍼즐 :

 | 1 2 3 | 4 5 6 | 7 8 9
-+-----------------------
A|   3   |     1 |
B|     6 |       |   5
C| 5     |       | 9 8 3
-+-----------------------
D|   8   |     6 | 3   2
E|       |   5   |
F| 9   3 | 8     |   6
-+-----------------------
G| 7 1 4 |       |     9
H|   2   |       | 8
I|       | 4     |   3

대답:

 | 1 2 3 | 4 5 6 | 7 8 9
-+-----------------------
A| 8 3 2 | 5 9 1 | 6 7 4
B| 4 9 6 | 3 8 7 | 2 5 1
C| 5 7 1 | 2 6 4 | 9 8 3
-+-----------------------
D| 1 8 5 | 7 4 6 | 3 9 2
E| 2 6 7 | 9 5 3 | 4 1 8
F| 9 4 3 | 8 1 2 | 7 6 5
-+-----------------------
G| 7 1 4 | 6 3 8 | 5 2 9
H| 3 2 9 | 1 7 5 | 8 4 6
I| 6 5 8 | 4 2 9 | 1 3 7

규칙 :

  1. 모든 미로를 논리만으로 해결할 수 있다고 가정하십시오.
  2. 모든 입력 길이는 81 자입니다. 누락 된 문자는 0입니다.
  3. 솔루션을 단일 문자열로 출력하십시오.
  4. "그리드"는 원하는대로 내부에 저장 될 수 있습니다.
  5. 솔루션은 추측 할 수없는 솔루션을 사용해야합니다. ( 스도쿠 솔버 참조 )

예제 I / O :

>sudoku.py "030001000006000050500000983080006302000050000903800060714000009020000800000400030"
832591674496387251571264983185746392267953418943812765714638529329175846658429137

실제로 시간 제한을 추가해야합니다.
JPvdMerwe

1
@ JPvdMerwe : 좋은 지적이지만 시간 제한은 표준화하기가 어렵습니다.
snmcdonald

1
@gnibbler : 이전에 수행되었을 수도 있지만 codegolf.se에서는 수행되지 않았습니다. 나는 특히 정직하게 행동한다면 커뮤니티에 가치를 더할뿐 아니라 해결하는 것이 여전히 재미있을 것이라고 생각합니다.
snmcdonald

2
난이게 좋아. 나는 실제 골프 솔루션을 시도하는 것을 망설이고 스도쿠 솔버를 작성하는 것에 대해 생각하고 있습니다 (재미있는 운동처럼 보입니다). 예전에는 골프를 본 적이없는 사람들이 점프 포인트로 사용할 수 있다고 생각합니다. 그리고 내가 하나를 생각해 내면 골프를 할 수 있습니다.
Andy

4
"논리만으로 해결할 수있는"문제는 매우 모호합니다. a) 기본 단계 만 사용한다는 의미입니까? a) 행, 열 및 블록에 값이없는 셀에 값을 작성합니다. b) 행, 열의 한 곳에만 들어갈 수있는 숫자 식별 또는 차단하고 거기에 쓰는가?
xnor

답변:


4

루비 ( 449436 문자)

I=*(0..8)
b=$*[0].split('').map{|v|v<'1'?I.map{|d|d+1}:[v.to_i]};f=b.map{|c|!c[1]}
[[z=I.map{|v|v%3+v/3*9},z.map{|v|v*3}],[x=I.map{|v|v*9},I],[I,x]
].map{|s,t|t.map{|i|d=[a=0]*10;s.map{|j|c=b[i+j];c.map{|v|d[v]+=1if !f[i+j]}
v,r=*c;s.map{|k|b[i+k].delete(v)if j!=k}if !r 
s[(a+=1)..8].map{|k|s.map{|l|b[i+l]-=c if l!=k&&l!=j}if c.size==2&&c==b[i+k]}}
v=d.index 1;f[i+k=s.find{|j|b[i+j].index v}]=b[i+k]=[v]if v}}while f.index(!1)
p b*''

예:

C:\golf>soduku2.rb 030001000006000050500000983080006302000050000903800060714000009020000800000400030
"832591674496387251571264983185746392267953418943812765714638529329175846658429137"

빠른 설명 :
보드 b는 각 셀에 가능한 모든 값을 보유하는 81 개의 배열로 구성된 배열입니다. 세 번째 줄의 배열에는 각 그룹 (상자, 행, 열)에 대한 [offset, start_index]가 있습니다. 그룹을 반복하는 동안 세 가지 작업이 수행됩니다.

  1. 크기가 1 인 셀의 값은 나머지 그룹에서 제거됩니다.
  2. 셀 쌍에 동일한 2 개의 값이 포함되어 있으면 나머지 그룹에서이 값이 제거됩니다.
  3. 각 값의 개수가 저장됩니다 d-값의 인스턴스가 하나 뿐인 경우 포함 셀을 해당 값으로 설정하고 셀을 고정 된 것으로 표시합니다f

모든 셀이 고정 될 때까지 반복하십시오.


에서 대괄호를 생략 I=*(0..8)하면 2자를 절약 할 수 있습니다 .
Dogbert

sudokusolver.rb:8: unterminated string meets end of file시작하면 얻을 수 있습니다 ruby1.8 sudokusolver.rb 030.... 내가 무엇을 잘못하고 있지?
사용자가 알 수 없음

마지막 줄에 추가 '가있는 것 같습니다. 어떻게 도착했는지 잘 모르겠습니다.
AShelly

2

프롤로그-493 자

:-use_module(library(clpfd)).
a(X):-all_distinct(X).
b([],[],[]).
b([A,B,C|X],[D,E,F|Y],[G,H,I|Z]):-a([A,B,C,D,E,F,G,H,I]),b(X,Y,Z).
c([A,B,C,D,E,F,G,H,I|X])-->[[A,B,C,D,E,F,G,H,I]],c(X).
c([])-->[].
l(X,Y):-length(X,Y).
m(X,Y):-maplist(X,Y).
n(L,M):-l(M,L).
o(48,_).
o(I,O):-O is I-48.
:-l(L,81),see(user),m(get,L),seen,maplist(o,L,M),phrase(c(M),R),l(R,9),m(n(9),R),append(R,V),V ins 1..9,m(a,R),transpose(R,X),m(a,X),R=[A,B,C,D,E,F,G,H,I],b(A,B,C),b(D,E,F),b(G,H,I),flatten(R,O),m(write,O).

산출:

입력 : 000000000000003085001020000000507000004000100090000000500000073002010000000040009 출력 : 987654321246173985351928746128537694634892157795461832519286473472319568863745219

입력 : 030001000006000050500000983080006302000050000903800060714000009020000800000400030 출력 : 832591674496387251571264983185746392267953418943812765714638529329175846658429137

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.