Sudoku bulmacalarının verimli kodlanması


16

Herhangi bir keyfi 9x9 ızgarasının belirtilmesi, her karenin konumunu ve değerini vermeyi gerektirir. Bunun için naif bir kodlama 81 (x, y, değer) üçlüsü verebilir ve her bir x, y ve 4 için bit olmak üzere toplam 81x4x3 = 972 bit değer gerektirir (1-9 = 9 değer = 4 bit). Her kareyi numaralandırarak, konum bilgisi 7 bite indirgenebilir, her kare için bir miktar ve toplam 891 bit düşebilir. Önceden belirlenmiş bir sipariş belirterek, toplam 324 bit için her değer için sadece 4 bite düşürülebilir. Bununla birlikte, bir sudoku'nun numaraları eksik olabilir. Bu, belirtilmesi gereken sayıların sayısını azaltma potansiyeli sağlar, ancak konumları göstermek için ek bitler gerektirebilir. (Pozisyon, değer) bizim 11-bit kodlama kullanarak, bir bulmaca belirtebilirsiniz n ile ipuçları 11n bit, örneğin minimal (17) bir bulmaca 187 bit gerektirir. Şimdiye kadar düşündüğüm en iyi kodlama, doldurulup doldurulmadığını göstermek için her boşluk için bir bit kullanmak ve eğer öyleyse, aşağıdaki 4 bit sayıyı kodlar. Bu81+4n bit, minimum bir bulmaca için 149 (n=17 ) gerektirir. Tercihen geçerli her sudoku kurulumunun bir veritabanı olmadan daha verimli bir kodlama var mı? (Genel bir adresleme için ekstra puan,n denN×N yapboz)

Bana sadece birçok bulmacanın bir diğerinin dönüşü olacağı veya basit bir rakam permütasyonu olacağı ortaya çıktı. Belki de bu, gerekli bitlerin azaltılmasına yardımcı olabilir.

Wikipedia'ya göre ,

Klasik 9 × 9 Sudoku çözüm ızgaralarının sayısı 6.670.903.752.021.072.936.960 (OEIS'de A107739 dizisi) veya yaklaşık 6.67×1021 .

Eğer matematik hakkımı yapsaydım ( ln(6,670,903,752,021,072,936,960)ln(2) ), bir arama tablosu için 73 (72.498) bit bilgi ortaya çıkar.

Fakat:

Döndürme, yansıtma, permütasyon ve yeniden etiketleme gibi simetriler dikkate alındığında, esasen farklı çözümlerin sayısının sadece 5,472,730,538 [15] (OEIS'de A109741 sekansı) olduğu gösterilmiştir.

Bu 33 (32.35) bit verir, böylece hangi permütasyonun tam 73 bitin altına düşebileceğini belirtmek için akıllı bir yöntem mümkündür.


1
Ha, başlangıçta sorunu yeterince düşünmeden bazı şeyler yayınladım. Sildim. Harika bir soru!
Patrick87

Kaç tane Sudoku bulmacasının olduğunu hatırlatabilir misiniz, bu yüzden bu kolayca çözülebilen kodlamalar ile kaba kuvvet sayımı arasındaki boşluğun ne kadar geniş olduğunu biliyoruz?
Gilles 'SO- kötü olmayı bırak

Tüm ızgaraları kodlayabilmeniz gerekir, bu nedenle 73 bite ihtiyacınız vardır (sabit uzunlukta kodlama varsayarak). "Hangi permütasyonun kullanılacağını belirten akıllıca bir yöntem" size yardımcı olmayacaktır. 6.67×1021
svick

Bir bilgi teorisi bakış açısından, haklı olmanız gerektiğini düşünüyorum, ancak ekstra bitlerin nereden geldiğini anlayamıyorum. Orada 19 bit artı ayna ve döndürme için 3, yani benzersiz bulmacalar için 22 artı 33 olan permütasyonlar 55; diğer 18 nereden geliyor? 9!
Kevin

Yanıtlar:


5

Tercihen geçerli her sudoku kurulumunun bir veritabanı olmadan daha verimli bir kodlama var mı?

Evet. Bir duruma bağlı olarak 6 veya 9 bitlik minimum bulmacanın 149 bit kodlamasını geliştiren bir kodlama düşünebilirim . Bu bir veritabanı veya başka çözümlerin veya kısmi kartların herhangi bir kaydı olmadan . İşte gidiyor:9×9

İlk olarak, bir sayı m'yi tahtada minimum sayıda görünümle kodlamak için bit kullanırsınız . Bir sonraki 4 bit gerçek sayı kodlayan kere m görüntülenir. Bir sonraki 7 bit hangi pozisyonların her kodlayan m görüntülenir.4m4m7m

Aşağıdaki bitleri, kalan konumların bir sayıya sahip olup olmadığını gösteren bayraklardır ( m'nin bulunduğu konumları atlamanız yeterlidir ). Bu bitlerden biri ne zaman olursa, sonraki 3 bit hangi sayının olduğunu belirtir (sıralı { 1 , , 9 } m'de olmadan ). Örneğin, m = 4 ve 3 bit ise , karttaki ilgili konumdaki sayı, { 1 , 2 , 3 kümesindeki 5. sayıdır (0'dan sayma) ,81m1{1,,9}mm=4101 , yani 6 . J < m sayılarıikili olarak j - 1 olarak kodlanırken, j > m sayıları j - 2 olarak kodlanır. Daha önce pozisyonlarıyazdığımıziçin, bu adımda kartın geri kalanını kodlamak içinsadece 3 ( n - ) bit eklenecektir.{1,2,3,5,6,7,8,9}6j<mj1j>mj23(n)

Bu nedenle, bu prosedürü kullanarak bir kartı kodlamak için gereken toplam bit sayısı

B=4+4+7+(81)+3(n)=89+3+3n.

İçin , bunu dikkat (genel olarak 0 ya da 1 olabilir N / 9 ). Böylece, tahtada görünmeyen bir sayı olmasına bağlı olarak B 140 veya 143 olabilir.n=17n/9B

Kevin'in çözümünün genel durumda çok daha iyi olduğunu belirtmek gerekir. Yalnızca en 149 bit bu kodlama kullanımları , veya için , n = 20 koşuluyla = 0 . En azından N =n{17,18,19}n=20=0 çok yakın olan 2 delinecek log 2 N 4 bit izin beri, değer başına 4 bit kullanarak biz "kaybetmek belleğe" eğilimi anlamına gelir ( N = 16 rakamını daifade etmemiz gerekiyor.N=92log2NN=16


Misal. ipucuna sahip aşağıdaki tabloyu düşünün .n=17

.  .  .   .  .  .   .  1  .
4  .  .   .  .  .   .  .  .
.  2  .   .  .  .   .  .  .

.  .  .   .  5  .   4  .  7
.  .  8   .  .  .   3  .  .
.  .  1   .  9  .   .  .  .

3  .  .   4  .  .   2  .  .
.  5  .   1  .  .   .  .  .
.  .  .   8  .  6   .  .  .

Burada hiçbir numara yok değil gemide görünür ve sayılar 6, 7 ve 9 yalnızca bir kez görünür. Biz almak ( ) ve = 1 ( ). Konumları soldan sağa ve sonra yukarıdan aşağıya doğru okurken, 36 ( ) konumunda m görünür . Böylece kodlamamız başlar .m=70111=10001m360100100011100010100100

Daha sonra, yedi mi 0s, tek 1ve numara 3-bit şifreleme , daha sonra , bir takip ve 3 bit kodlama 4 , vb ( ). Sonunda, m = 7 olduğu pozisyonu atlayacağız ve 8 olarak kodlayacağız (6. sayı listede 0'dan sayılıyor10140000000100101100m=7110) ve 9 olarak. Tam kodlama aşağıdaki gibidir:1,2,3,4,5,6,8,9111

// m=7, l=1 and its position on the board.
011100010100100
// Numbers 1 and 4 at the beginning. Note that 1 is encoded 000, and 4 is 011.
0000000100001011
// Numbers 2 and 5.
0000000001001000000000001100
// Numbers 4 and 8. We skip the appearance of 7 and encode 8 as 110.
010110001110
// 3, 1 and 9. 9 is encoded as 111.
00010100000100001111
// 3, 4, 2, 5, 1, 8, 6 and the last empty cells.
0000101000101100100100011000100000000000111001101000

Kodlamanın tamamı 01110001010010000000001001010110000000001001000000000001100010110001110000101000001000011110000101000101100100100011000100000000000111001101000ve okuyucu bu dizenin uzunluğunu gerçekten kontrol edebilir 143 :-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.