ใช้ตัวแก้ซูโดกุแบบไม่ต้องเดา


27

ใช้ตัวแก้ Sudoku ที่สั้นที่สุด

ปริศนา Sudoku:

 | 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. โซลูชันต้องใช้โซลูชันที่ไม่คาดเดา (ดูSudoku Solver )

ตัวอย่าง I / O:

>sudoku.py "030001000006000050500000983080006302000050000903800060714000009020000800000400030"
832591674496387251571264983185746392267953418943812765714638529329175846658429137

คุณควรเพิ่มการ จำกัด เวลาจริงๆ
JPvdMerwe

1
@JPvdMerwe: จุดดี แต่การ จำกัด เวลาจะยากที่จะสร้างมาตรฐาน
snmcdonald

1
@gnibbler: อาจเคยทำมาก่อน (แต่ไม่ใช่ codegolf.se) ฉันคิดว่ามันจะยังสนุกที่จะแก้ไขและเพิ่มคุณค่าให้กับชุมชน
snmcdonald

2
ฉันชอบอันนี้ ฉันลังเลที่จะลองใช้วิธีแก้ปัญหากอล์ฟจริง ๆ และฉันก็คิดที่จะเขียนแก้ปัญหา Sudoku (ดูเหมือนการออกกำลังกายที่สนุก) ฉันคิดว่ามันเป็นสิ่งที่คนอย่างฉันที่ไม่เคยเล่นกอล์ฟมาก่อนสามารถใช้เป็นจุดกระโดดได้ และเมื่อฉันเกิดขึ้นกับฉันฉันอาจเล่นกอล์ฟ
Andy

4
ปัญหา "แก้ไขได้ด้วยตรรกะเท่านั้น" นั้นคลุมเครือมาก คุณหมายถึงอาจใช้เพียงขั้นตอนพื้นฐานของ a) การเขียนค่าในเซลล์ที่ค่าไม่ได้อยู่ในแถวคอลัมน์และบล็อก b) การระบุหมายเลขที่สามารถไปในที่เดียวในแถวคอลัมน์ หรือบล็อกและเขียนที่นั่นหรือ
xnor

คำตอบ:


4

RUBY ( 449 436 ตัวอักษร)

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"

คำอธิบายอย่างรวดเร็ว:
Board bเป็นอาร์เรย์จำนวน 81 อาร์เรย์ที่เก็บค่าที่เป็นไปได้ทั้งหมดสำหรับแต่ละเซลล์ อาร์เรย์ในบรรทัดที่สามมี [ออฟเซต, start_index] สำหรับแต่ละกลุ่ม (กล่อง, แถว, คอลัมน์) มีการทำงานสามอย่างในขณะที่วนกลุ่ม

  1. ค่าของเซลล์ขนาด 1 ใด ๆ จะถูกลบออกจากส่วนที่เหลือของกลุ่ม
  2. หากคู่ของเซลล์ใดมีค่า 2 ค่าเดียวกันค่าเหล่านี้จะถูกลบออกจากส่วนที่เหลือของกลุ่ม
  3. จำนวนของแต่ละค่าจะถูกเก็บไว้ในd- หากมีเพียง 1 อินสแตนซ์ของค่าเราจะตั้งค่าเซลล์ที่มีค่านั้นและทำเครื่องหมายเซลล์ในf

ทำซ้ำจนกว่าเซลล์ทั้งหมดจะได้รับการแก้ไข


คุณสามารถละเว้นวงเล็บในI=*(0..8)จะบันทึก 2 ตัวอักษร
Dogbert

ฉันจะได้รับถ้าผมเริ่มต้นด้วยsudokusolver.rb:8: unterminated string meets end of file ruby1.8 sudokusolver.rb 030...ผมทำอะไรผิดหรือเปล่า?
ผู้ใช้ไม่รู้จัก

ดูเหมือนว่าจะมีการเพิ่ม 'ในบรรทัดสุดท้าย ไม่แน่ใจว่าการที่ได้มี ...
AShelly

2

Prolog - 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.