Sudoku Çözücü
Boş hücrelere rakam deneyip kural bozulunca geri dönen, geri izlemenin en tanıdık örneği.
Önce bunlara göz at
#Nasıl çalışır?
Sudoku, geri izlemenin en tanıdık örneklerinden biridir. n × n bir tabloda her satır, her sütun ve her kutu 1'den n'e kadar rakamları birer kez içermelidir. Bu derste animasyon okunabilir kalsın diye 4 × 4'lük, 2 × 2 kutulu bir bulmaca kullanılıyor; yöntem 9 × 9 için de aynıdır.
Algoritma ilk boş hücreyi bulur ve sırayla 1, 2, … rakamlarını dener. Aynı satırda, sütunda ya da kutuda zaten bulunan bir rakam atlanır. Uygun bir rakam yazılır ve bir sonraki boş hücreye geçilir.
Bir hücre için hiçbir rakam uymazsa önceki bir seçim yanlıştır: son yazılan rakam silinir ve o hücre için sıradaki rakam denenir. Örnek bulmaca tek çözümlüdür ve çözülürken iki kez geri dönmek gerekir.
#Kendin dene
4 × 4 Sudoku: her satır, sütun ve 2 × 2 kutuda 1-4 rakamları birer kez bulunmalı. Boş hücreleri sırayla dolduruyor, çıkmazda geri dönüyoruz.
#Adım adım
- 01İlk boş hücreyi bul; yoksa bulmaca çözüldü.
- 02Hücreye 1'den n'e kadar rakamları sırayla dene.
- 03Rakam satır, sütun ve kutu kurallarına uyuyorsa yaz ve bir sonraki boş hücreye geç.
- 04Hiçbir rakam uymazsa geri dön: önceki hücredeki rakamı sil ve onun sıradaki rakamını dene.
#Örnek kod
Aynı algoritma 8 dilde. Her program derlenip çalıştırılarak test edildi ve hepsi aynı çıktıyı veriyor.
N, BOX = 4, 2 # a 4 x 4 puzzle with 2 x 2 boxes; the same code solves 9 x 9 with N, BOX = 9, 3
grid = [
[0, 0, 0, 0],
[0, 0, 1, 2],
[2, 0, 0, 4],
[0, 4, 0, 0],
]
def fits(r: int, c: int, d: int) -> bool:
if d in grid[r] or any(grid[k][c] == d for k in range(N)):
return False
br, bc = r - r % BOX, c - c % BOX
return all(grid[br + i][bc + j] != d for i in range(BOX) for j in range(BOX))
def solve() -> bool:
for r in range(N):
for c in range(N):
if grid[r][c] == 0: # the first empty cell
for d in range(1, N + 1):
if fits(r, c, d):
grid[r][c] = d
if solve():
return True
grid[r][c] = 0 # dead end: backtrack
return False
return True # no empty cell left
solve()
for row in grid:
print(" ".join(map(str, row)))#Karmaşıklık
| İşlem | Süre |
|---|---|
| En kötü durum | O(n^(boş hücre sayısı)) |
| Bir rakamı kontrol (tarama) | O(n) |
| Kümelerle kontrol | O(1) |
| Bellek | O(n²) |
Teoride üsteldir; pratikte kurallar dalları o kadar erken keser ki 9 × 9 bulmacalar milisaniyeler içinde çözülür. En az seçeneği olan hücreyi önce doldurmak (MRV sezgisi) ve her satır/sütun/kutu için kullanılan rakam kümeleri tutmak aramayı çok hızlandırır.
#Ne zaman kullanılır?
Sudoku ve benzeri bulmacalar (KenKen, Kakuro), kısıt sağlama problemleri, ders ve sınav programları, graf boyama ve kaynak atama problemleri aynı "dene, kontrol et, gerekirse geri al" kalıbıyla çözülür.
#Alıştırma
Soruları cevaplamak ve ilerlemeni kaydetmek için giriş yap.
Kolay
Sudoku çözücü bir hücreye hangi rakamı yazabilir?
- 1Aynı satır, sütun ve kutuda bulunmayan bir rakamı
- 2Herhangi bir rakamı
- 3Yalnızca 1'i
- 4Bir önceki hücreyle aynı rakamı
Bir hücreye hiçbir rakam uymazsa ne olur?
- 1Önceki hücredeki rakam silinir ve onun için sıradaki rakam denenir
- 2Bulmaca çözülmüş sayılır
- 3Rastgele bir rakam yazılır
- 4Baştan başlanır
4 × 4 Sudoku'da kutular kaç × kaçtır?
- 12 × 2
- 24 × 4
- 31 × 4
- 43 × 3
Orta
Hangi sezgi Sudoku çözümünü genellikle en çok hızlandırır?
- 1En az seçeneği olan hücreyi önce doldurmak (MRV)
- 2Hücreleri rastgele sırayla doldurmak
- 3Önce 9'ları yerleştirmek
- 4Kutuları atlamak
Zor
Bir rakamın uygun olup olmadığını O(1)'de kontrol etmek için ne tutulabilir?
- 1Her satır, sütun ve kutu için kullanılan rakamların kümesi (ya da bit maskesi)
- 2Tüm çözümlerin listesi
- 3Sıralı bir rakam dizisi
- 4Bir yığın