Bir sudoku çözümü yaratın CHECKER


21

Sudoku çözümü CHECKER oluşturun

Burada Sudoku SOLVERS'ın omletleri var, ama insanca olabildiğince küçük bir çözüm CHECKER (kod-golf) oluşturmanızı istiyorum.

  • Geçerli bir giriş, 9x9 dizisini bağımsız değişken olarak alabilir (referansla iletilir, komut satırında serileştirilmiş veya yine de almak isterseniz) veya son ızgara için dokuz satırlık dokuz satırlık bir giriş dosyasını kabul edebilir . Aşağıdaki girdi örneklerine bakın.

  • Geçerli giriş 10-rakamlı (1-9) olmalıdır.

  • Eksik, boş, ekstra, sayısal olmayan pozisyonlar veya 1-9 dışında sayıları olan pozisyonlar sıfır olmayan bir sonuç döndürülerek, bir hata yazdırılarak veya her ikisiyle de geçersiz giriş olarak reddedilmelidir.

  • Programınızın, her sayının sütun başına bir kez, satır başına bir kez ve 3x3 alt ızgara başına bir kez görünüp görünmediğini test etmesi gerekir. Geçerse, "0" döndür ve eğer değilse sıfır olmayan bir sonuç döndür.

  • Dış kaynakların (web siteleri vb.) Kullanımından kaçınılmalıdır.

  • Çözümünüz bağımsız bir programsa, "0" veya "Pass" veya "Fail" için sırasıyla "0" veya sıfır olmayan bir çıkış durumundan çıkılması veya yazdırılması tamamdır.

En küçük cevabı kazansın!

Giriş Örnekleri:

c dizisi:

int input[9][9]={{1,2,3,4,5,6,7,8,9},
                 {4,5,6,7,8,9,1,2,3},
                 {7,8,9,1,2,3,4,5,6},
                 {2,3,1,5,6,4,8,9,7},
                 {5,6,4,8,9,7,2,3,1},
                 {8,9,7,2,3,1,5,6,4},
                 {3,1,2,6,4,5,9,7,8},
                 {6,4,5,9,7,8,3,1,2},
                 {9,7,8,3,1,2,6,4,5}
                };

dosya:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

9 alt ızgara:

+---+---+---+
|123|456|789|
|456|789|123|
|789|123|456|
+---+---+---+
|231|564|897|
|564|897|231|
|897|231|564|
+---+---+---+
|312|645|978|
|645|978|312|
|978|312|645|
+---+---+---+

Yanıtlar:


5

GolfScript, 39 karakter

.zip.{3/}%zip{~}%3/{[]*}%++{$10,1>=!},,

Girdi olarak bir dizi dizisini alır ( çevrimiçi örneğe bakın ) ve 0geçerli bir ızgaraysa çıktısını alır .

Kodun kısa açıklaması

.zip         # Copy the input array and transpose it
.{3/}%       # Split each line into 3 blocks
zip{~}%      # Transpose these blocks
3/{[]*}%     # Do the same for the lines themselves and join again
++           # Make one large list of 27 9-element arrays 
             # (9 for rows, 9 for columns, 9 for blocks)
{$10,1>=!},  # From those 27 select the ones which are not a permutation of [1 2 3 ... 9]
             #   $      -> sort
             #   10,1>  -> [1 2 3 ... 9]
             #   =!     -> not equal
,            # Count after filtering

Kodunuzun sıfır olmayan çıktısının sadece 1ya da daha anlamlı olmasını seviyorum-1
David Wilkins

Cevabını gerçekten beğendim ama sonunda bir golfscript çözümü ile gitmemeyi seçtim. Gerçekten umarım anlarsın
David Wilkins

2
@DavidWilkins Aslında anlamıyorum - kuralları sen koydun (!) Ve GolfScript’e izin verilmediğini hiçbir yerde belirtmedin.
Howard,

Senin amacın tamamen geçerli ... aslında cevabını seçmemeyi haklı çıkaracak hiçbir şeyim yok. İyi oynadı
David Wilkins

10

Python, 103

Sudoku'dan nefret ediyorum.

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

e=enumerate;print 243-len(set((a,t)for(i,r)in e(b)for(j,t)in e(r)for a in e([i,j,i/3*3+j/3]*(0<t<10))))

Nasıl çalışır: her satır, sütun ve blokta 1'den 9'a kadar her sayı bulunmalıdır. Yani her biri 0 <= i, j < 9için hücre i,jblok içindedir 3*floor(i/3) + floor(j/3). Dolayısıyla, karşılanması gereken 243 gereksinim vardır. Her şart tuple yapmak 0 (dahil) ila 8 arası bir sayı, anlamında olabildikleri satır, sütun 0,1 ya da 2'dir ya da sırasıyla bloke eder ve giriştir .((item index,item type number),symbol)item indexitem type numbersymbolb[i][j]

Düzenleme: Yanlışlıkla geçerli girişleri kontrol etmedim. Şimdi yapıyorum


0Çözüm geçerse programınız çıkmalıdır ,True
David Wilkins

@DavidWilkins ne garip bir gereksinimdir. Sabit.
stand

Siz beyefendi, cevabınızı başlattığınız şekilde oyumu alıyorsunuz: D
Teun Pronk

9

APL (46)

{∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵}

Bu 9'a 9'luk bir matris alır. Örnek bir TryAPL'de şu şekilde girilebilir:

     sudoku ← ↑(1 2 3 4 5 6 7 8 9)(4 5 6 7 8 9 1 2 3)(7 8 9 1 2 3 4 5 6)(2 3 1 5 6 4 8 9 7)(5 6 4 8 9 7 2 3 1)(8 9 7 2 3 1 5 6 4)(3 1 2 6 4 5 9 7 8)(6 4 5 9 7 8 3 1 2)(9 7 8 3 1 2 6 4 5)
     {∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵} sudoku
1

Açıklama:

  • ↓⍉⍵: sütunlarını al ,
  • ↓⍵: Satırlarını almak ,
  • 3/3⌿3 3⍴Z←⍳9: Sayıları içeren bir 3-ile-3 matris yapmak 1için 9, daha sonra numaraları ile 9 9 tarafından matris veren her iki yönde de her numara, üç kopya halinde 1için 9, her bir grup gösteren
  • Z∘.=: her sayı 1için 9verilen grup için bir bit maskesi yapın,
  • /∘(,⍵)¨: ve gruplarla birlikte her birini maskeleyin .
  • ∊∘Z¨: O rakamlarını içeriyorsa her bir alt dizisi için bkz 1üzere 9,
  • ∧/,↑: andtüm bu sayıların mantığını beraber alın.

+1 Güzel! Ancak 3 × 3 grupları biraz daha golf oynayabilir. Örneğin, bu ↓9 9⍴1 3 2⍉3 3 9⍴⍵eşdeğerdir /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9ancak oldukça kısadır. Eminim daha kısa formüller vardır.
Tobia,

Ayrıca matrisleri 1. boyuta göre birleştirebilir ve sonunda tek bir bölünme gerçekleştirebilirsiniz:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

Bir hata var: bu kod ∊∘Z¨, her bir alt dizinin (satır, sütun veya blok) yalnızca 1'den 9'a kadar sayılardan oluşup oluşmadığını test ediyor. Tüm sayıların temsil edilip edilmediğini test etmiyor. Z∘.∊Her alt dizide Z'deki her sayının bulunduğunu test eden bir şey yapmanız gerekir .
Tobia,

Ve bu ∧/,↑kısaltılabilir ∧/∊. Ben bittim, bittim! ;-)
Tobia

Çok kompakt, ama hemen görebildiğim kritik bir noktayı kaçırdınız:If it passes, return "0" and if not, return a non-zero result.
David Wilkins

5

Java / C # - 183/180 181/178 173/170 bayt

boolean s(int[][]a){int x=0,y,j;int[]u=new int[27];for(;x<(y=9);x++)while(y>0){j=1<<a[x][--y];u[x]|=j;u[y+9]|=j;u[x/3+y/3*3+18]|=j;}for(x=0;x<27;)y+=u[x++];return y==27603;}

(Değiştir booleaniçin boolC # için)

biçimlendirilmiş:

boolean s(int[][] a){
    int x=0, y, j;
    int[] u=new int[27];
    for(;x<(y=9);x++)
        while(y>0){
            j=1<<a[x][--y];
            u[x]|=j;
            u[y+9]|=j;
            u[x/3+y/3*3+18]|=j;
        }

    for(x=0;x<27;)
        y+=u[x++];

    return y==27603;
}

Yöntem u, dokuz satır, sütun ve karede bulunan rakamları temsil eden 27 bit maskeli bir dizi oluşturur .

Daha sonra tüm hücreleri 1 << a[x][y]yineleyerek, basamağı temsil eden bir bit maskesi oluşturma işlemini gerçekleştirir ve bununla birlikte sütununu, satırını ve kare bit maskesini belirtir.

Daha sonra, tüm 27 bit maskesinin üzerinde yinelenerek hepsinin 27594'e kadar eklenmesini sağlar (1022 * 9, 1022, tüm 1-9 basamakları için bit maskesidir). ( yÇift döngüyü izleyen 9 zaten içerdiğinden dolayı 27603 olarak sona ereceğini unutmayın .)

Düzenleme: Yanlışlıkla %3artık gerekli olmayan bir bırakma.

Düzenleme 2: Bryce Wagner'in yorumundan ilham alan kod biraz daha sıkıştırıldı.


Hemen hemen aynı algoritma C # 149 karakterlerinde (ancak sadece Linq'e izin verilirse): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y = 9)) (y> 0) {j = 1 << bir süre [x + 9 * - y]; u [x] '| = j; u [y + 9] | = j; u [x / 3 + y / 3 * 3 + 18] | = j;} return u.Sum () == 27594;}
Bryce Wagner

@BryceWagner Linq gerçekten yararlı olurdu. Ancak benim çözümüm Java için C # ile bir düşünce (orijinal yazıda bile belirtilmemiş) ve dolayısıyla daha düşük önceliğe sahip olmak. Ayrıca, buna karşı karar vermeden önce başlangıçta kompaktlık için tek boyutlu diziler kullandım (örnekler iki boyutlu olanları kullandıkça). Bununla birlikte, kodunuz birkaç baytın nasıl tıraş edilebileceği konusunda bana birkaç fikir verdi. :)
Smallhacker

3

python = 196

En çok golf oynamak değil, ama fikir orada. Kümeler oldukça kullanışlıdır.

Yazı tahtası:

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

Programı:

n={1,2,3,4,5,6,7,8,9};z=0
for r in b:
 if set(r)!=n:z=1
for i in zip(*b):
 if set(i)!=n:z=1
for i in (0,3,6):
 for j in (0,3,6):
  k=j+3
  if set(b[i][j:k]+b[i+1][j:k]+b[i+2][j:k])!=n:z=1
print(z)

s / {1,2,3,4,5,6,7,8,9} / set (aralık (1,10)) / 3 karakter kaydeder.
MatrixFrog

Python 3.5'te kullanabilirsiniz n={*range(1,10)}, ancak bu zorluktan daha yeni. Bunun yerine set(range(1,10))MatrixFrog'un söylediği gibi kullanın .
mbomb007

3

Java - 385 306 328 260 karakter

Düzenleme: cevap bu aptalca talimatları yanlış yorumlamak vardı tam bir program olarak. Yalnızca geçerli bir işlev olabileceğinden, işlev olarak yeniden yazdım ve simge durumuna küçültdüm ve çözüm girişimi bununla birlikte yeniden yazdım.

Bu yüzden, kendime bir meydan okuma olarak en küçük Java çözüm denetleyicisini yapmaya çalışacağımı düşündüm.

Bunu başarmak için, sudoku bulmacasının, java çok boyutlu bir dizi olarak geçirileceğini farz ediyorum:

s(new int[][] {
    {1,2,3,4,5,6,7,8,9},
    {4,5,6,7,8,9,1,2,3},
    {7,8,9,1,2,3,4,5,6},
    {2,3,1,5,6,4,8,9,7},
    {5,6,4,8,9,7,2,3,1},
    {8,9,7,2,3,1,5,6,4},
    {3,1,2,6,4,5,9,7,8},
    {6,4,5,9,7,8,3,1,2},
    {9,7,8,3,1,2,6,4,5}});

Ardından, geçerli çözüm varsa "0", değilse "1" döndüren gerçek çözücümüz var.

Tamamen golf:

int s(int[][] s){int i=0,j,k=1;long[] f=new long[9];long r=0L,c=r,g=r,z=45L,q=r;for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}for(;i<9;i++){for(j=0;j<9;){k=s[i][j];r+=k*f[i];c+=k*f[j];g+=k*f[j++/3+3*(i/3)];q+=5*f[k-1];}}return (r==z&&c==z&&g==z&&q==z)?0:1;}

Okunabilir:

    int s(int[][] s) {
        int i=0,j,k=1;
        long[] f=new long[9]; 
        long r=0L,c=r,g=r,z=45L,q=r;
        for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}
        for(;i<9;i++) {
            for (j=0;j<9;) {
                k=s[i][j];
                r+=k*f[i];
                c+=k*f[j];
                g+=k*f[j++/3+3*(i/3)];
                q+=5*f[k-1];
            }
        }
        return (r==z&&c==z&&g==z&&q==z)?0:1;
    }

Peki bu nasıl çalışıyor? Temelde, her basamakta yeterli çözünürlüğe sahip kendi sayı tabanımı yarattım, bulmacanın üzerinden geçtikten sonra geçerli olup olmadığını bilmek için yalnızca üç sayısal karşılaştırma yapmak zorunda kaldım. Bu problem için üs 49'u seçtim, ancak 45'ten büyük olan bazlar yeterli olacaktır.

A (umarım) açık bir örnek: sudoku bulmacasındaki her "satır" ın temel-49 sayısında tek bir rakam olduğunu hayal edin. Temellik-49 sayısındaki her basamağı basitlik için bir vektördeki temel-10 sayı olarak temsil edeceğiz. Bu nedenle, eğer tüm satırlar "doğru" ise, şu ana-49 sayısını (bir taban-10 vektörü olarak) bekliyoruz:

(45,45,45,45,45,45,45,45,45)

veya tek bir taban-10 numarasına dönüştürülür: 1526637748041045

Tüm sütunlar için aynı mantığı, "alt ızgaralar" için de aynı mantığı izleyin. Son analizde bu "ideal sayı" 'ya eşit olmayan herhangi bir değer, bulmaca çözümünün geçersiz olduğu anlamına gelir.

5'inin güvenlik açığını ve diğer ilgili sorunları çözmek için düzenleyin: Her yapbozda her sayının 9 olması gerektiği fikrine dayanarak dördüncü bir üs-49 numarası eklerim. Böylece, basamağın endeksini temsil eden baz-10 sayısının her bir oluşumu için baz-49 sayısındaki her bir basamağa 5 eklerim. Bir örnek, eğer 10 9 ve 9 8, 9 7, 8 6 ve 9 tanesinin hepsinde, bir taban-49 numarası alırsınız (taşma ile başa çıkmak için 10'luk bir taban-10 vektörü olarak):

(1, 1, 45, 45, 40, 45, 45, 45, 45, 45)

"İdeal" üss-49 numaramız ile kıyaslandığında başarısız olacak.

Benim çözümüm, mümkün olduğunca döngü ve karşılaştırma yapmaktan kaçınmak için bu matematiksel çözümden yararlanır. longHer bir baz-49 sayısını bir baz-10 numarası olarak saklamak için bir değer kullanıyorum ve sütun / satır / alt-kontrol kontrolü değer hesaplaması sırasında her bir baz-49 basamağının "faktörlerini" almak için bir arama dizisi kullanıyorum.

Java özlü olarak tasarlanmadığından, matematiksel yapıya dikkat etmek özlü bir denetleyici kurabileceğimi düşündüğüm tek yoldu.

Ne düşündüğü söyle.


1
Aslında, bu durum @ steve-verrill tarafından belirtilen aynı güvenlik açığından muzdariptir - 5'in tümü veya 45'i toplayan herhangi bir sayı seti, çözücüyü "kandırır". Ben revize edeceğim. Bunu nasıl yeneceğime dair bir fikrim var.
ProgramcıDan

En son güncellememdeki bu güvenlik açığını giderdim. Şimdi bu dava ve türünün tüm diğerleriyle ilgileniliyor. Temel olarak, her 10 baz tip hanenin “sayıları” ile ilgilenmemek ciddi bir gözetimdi. Şimdi doğrudan bu kontrolü yapıyorum, ancak aynı matematiksel yaklaşımı kullanarak (üs-49 sayı).
ProgramcıDan

Dan, teşekkür için teşekkürler. Onu gördüm ve neden haberdar edilmediğimi merak ettim, ama ismime bir çizgi koyduğunuzu görüyorum. Bu sistemin kafasını karıştırmış gibi görünüyor. Sadece boşluğu atlayın. İsmimin gösterilme şeklini değiştirmeyi düşüneceğim.
Seviye Nehri St

Ahha, bu onu açıklar. Thanks @steveverrill - Hala bir şeyler yapmanın stackexchange yoluna alışmaya başladım. Bununla birlikte, toplam 45 ilkesinden özlediğiniz istismarın zekice ifade edildi. Çözümümü üstesinden gelmek için daha uzun yaptım, ama bu hayat!
ProgramcıDan



2

Perl, 193 bayt

for(@x=1..9){$i=$_-1;@y=();push@y,$a[$i][$_-1]for@x;@y=sort@y;$r+=@y~~@x;@y=();push@y,$a[3*int($i/3)+$_/3][3*($i%3)+$_%3]for 0..8;@y=sort@y;$r+=@y~~@x}for(@a){@y=sort@$_;$r+=@y~~@x}exit($r!=27)

Dizi biçiminde giriş bekleniyor:

@a=(
    [1,2,3,4,5,6,7,8,9],
    [4,5,6,7,8,9,1,2,3],
    [7,8,9,1,2,3,4,5,6],
    [2,3,1,5,6,4,8,9,7],
    [5,6,4,8,9,7,2,3,1],
    [8,9,7,2,3,1,5,6,4],
    [3,1,2,6,4,5,9,7,8],
    [6,4,5,9,7,8,3,1,2],
    [9,7,8,3,1,2,6,4,5]
);

@aBir çözüm ise , çıkış kodu 0 , aksi takdirde 1döndürülür.

Ungolfed versiyonu:

@x = (1..9);
for (@x) {
    $i = $_ - 1;
    # columns
    @y = ();
    for (@x) {
        push @y, $a[$i][$_-1];
    }
    @y = sort @y;
    $r += @y ~~ @x;
    # sub arrays
    @y = ();
    for (0..8) {
        push @y, $a[ 3 * int($i / 3) + $_ / 3 ][ 3 * ($i % 3) + $_ % 3 ];
    }
    @y = sort @y;
    $r += @y ~~ @x
}
# rows
for (@a) {
    @y = sort @$_;
    $r += @y ~~ @x
}
exit ($r != 27);

9 satır, 9 sütun ve 9 alt dizinin her biri bir diziye yerleştirilir ve diziye uyup uymadığı kontrol edilir (1..9). $rGeçerli bir çözüm için 27'ye kadar toplaması gereken her başarılı maç için sayı artırılır.


2

J 52 54

-.*/,(9=#)@~.@,"2(0 3 16 A.i.4)&|:(4#3)($,)".;._2]0 :0

Komut satırına yapıştırılan, a) ile biten argümanını alır:

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
)

Geçilirse 1, değilse 0 döndürür.

Dahili olarak, 9x9 ızgarayı 3x3x3x3 ızgaraya dönüştürür ve eksenlerin üzerinde istenen 2 birimi (satırlar, çizgiler ve kutular) almak için son 2 boyutta bazı permütasyonlar yapar.

Bunu yaptıktan sonra, her birimin 9 benzersiz değeri olduğu kontrol edilir.

Muhtemelen kusursuz olmaktan uzak, ama zaten çoğunluğu yeniyor ;-)


İlk bakışta, diğerlerinden bazıları ile aynı şartla yakalandınız… İadeleriniz ters çevrilmelidir ... Geçiş için 0, başarısızlık için sıfır olmayan
David Wilkins

Geçiş için 0 aptalca. Boole’un doğru için 1’i, yanlış için 0’ı seçmesinin bir nedeni vardır. Fakat haklısın. 2 karakter ekler.
jpjacobs

Bir çıkış durumu olarak düşünün, boolean bir değer değil
David Wilkins

Cevabınızı seçiyorum çünkü işe yarıyor. Kurallara uydun ve programın çok kısa. Teşekkürler!
David Wilkins

Peki ben lifli ... Gerçekte sizinkinden daha kısa olan bir Golfscript cevabını seçmemeyi haklı çıkaramıyorum ... Ama 2. sıra için övgüler
David Wilkins

2

Mathematica, 84 79 karakter

f=Tr[Norm[Sort@#-Range@9]&/@Join[#,Thread@#,Flatten/@Join@@#~Partition~{3,3}]]&

Örnekler:

f[{{1,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

0

f[{{2,1,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

2

f[{{0,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

3


Üçüncü çıkış örneğiniz: Her 3zaman geçersiz girişin göstergesi mi , yoksa bazen başarısız bir çözüme cevap mı?
David Wilkins

2

Javascript ES6, 150 karakter

Herhangi bir sınırlayıcı olmadan girişi 81 karakterlik bir dize olarak alır.

s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))

İşlev null, negatif cevap olarak ve ilk elemanda pozitif olan olarak orijinal dizgiye sahip bir dizi döndürür . !!Başlangıç ​​fonksiyonuna ekleyerek bool değişebilir .

Test ( daha fazla bilgi için ilgili zorluğa bakınız ):

f=s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(f)
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !f(s))

Bu çok saçma bir regex ... Şaşırtıcı iş.
ETH Sunumları

2

R, 6350 bayt

Girişin m9x9 sayı matrisi olduğunu varsayar .

all(apply(m,1,match,x=1:9),apply(m,2,match,x=1:9))

Daha fazla golf oynamanın mümkün olduğu konusunda haklıydım.

Açıklama:

    apply(m,1,match,x=1:9),

Al mve her satır için matchişlevi uygula . Biz başka bir argüman belirtmek x=1:9geçirilecek match. xvarsayılan birinci konum argümanıdır ve bu nedenle her bir satır olan ikinci argüman konumuna yerleştirilir table. İşlev match, xiçindeki örnekleri arar table. Bu durumda, 1:9her satırda (1'den 9'a kadar olan sayıları) arar . Her biri için 1:9, bu sayı bulunursa (yoksa) döndürür TRUE(veya FALSE).

Yani, bu bir dizi 81 boolean değer verir.

                           apply(m,2,match,x=1:9)

Girişin her sütunu için yukarıdakileri tekrarlayın.

all(                                             )

Son olarak, allboolean listesinin her unsurunun olup olmadığını kontrol eder TRUE. Bu, ancak çözümün doğru olması durumunda geçerli olacaktır (yani, her sayı 1:9her sütunda ve her satırda yalnızca bir kez bulunur).

Eski yaklaşım:

for(i in 1:2)F=F+apply(m,i,function(x)sort(x)==1:9);sum(F)==162

Her satırı alır, sıralar ve sonra karşılaştırır [1, 2, ... 9]. Doğru bir satır tam olarak eşleşmelidir. Sonra her sütun için aynı şeyi yapar. Toplamda 162 kesin eşleşmemiz gerekiyor, ki bu da son bölümün kontrol ettiği şey. Burada daha fazla golf oynamak için büyük olasılık var.


Sütunları ve satırları kontrol ediyor gibisiniz ama kutular için değil ...
JayCe

1

Haskell - 175

import Data.List
c=concat
m=map
q=[1..9]
w=length.c.m (\x->(x\\q)++(q\\x))
b x=c.m(take 3.drop(3*mod x 3)).take 3.drop(3*div x 3)
v i=sum$m(w)[i,transpose i,[b x i|x<-[0..8]]]

İşlev çağrılacak işlevdir v. Her satırın, sütununun ve bloğun listedeki [1..9]farkını alıp bu fark listelerinin uzunluklarını toplayarak çalışır.

Sudoku örneğini kullanarak demo:

*Main> :l so-22443.hs 
[1 of 1] Compiling Main             ( so-22443.hs, interpreted )
Ok, modules loaded: Main.
*Main> v [[1,2,3,4,5,6,7,8,9],[4,5,6,7,8,9,1,2,3],[7,8,9,1,2,3,4,5,6],[2,3,1,5,6,4,8,9,7],[5,6,4,8,9,7,2,3,1],[8,9,7,2,3,1,5,6,4],[3,1,2,6,4,5,9,7,8],[6,4,5,9,7,8,3,1,2],[9,7,8,3,1,2,6,4,5]]
0

1

Javascript - 149 Karakterler

r=[];c=[];g=[];for(i=9;i;)r[o=--i]=c[i]=g[i]=36;for(x in a)for(y in z=a[x]){r[v=z[y]-1]-=y;c[v]-=x;g[v]-=3*(x/3|0)+y/3|0}for(i in r)o|=r[i]|c[i]|g[i]

Bir dizinin var aolmasını bekler ve oçıktı 0için başarılı, sıfır olmayan bir değişken oluşturur .

Her satır, sütun ve 3 * 3 ızgara için her bir değerin gerçekleştiği pozisyonun toplamının 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8) olduğunu kontrol ederek çalışır.

Test yapmak

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,4,5]
  ];

'O = 0' verir

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,5,4]
  ];

(Son 2 hane değiştirildi)

verir o=-1

a=[
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5]
  ];

verir o=-284


1

Haskell, 121 130 127 bayt (87 Lambdabot)

import Data.List
import Data.List.Split
c=concat
t=transpose
k=chunksOf
p x=all(==[1..9])$(sort<$>)=<<[x,t x,k 9.c.c.t$k 3<$>x]

kullanımları:

-- k 9.c.c.t$k 3<$> x = chunksOf 9 $ concat $ concat $ transpose $ map chunksOf 3 x

let ts = k 9$[10*a+b|a<-[1..9],b<-[1..9]] --yep, this is ugly
in k 9.c.c.t$k 3<$>ts
-- prints:
--[[11,12,13,21,22,23,31,32,33],[41,42,43,51,52,53,61,62,63],[71,72,73,81,82,83,91,92,93],[14,15,16,24,25,26,34,35,36],[44,45,46,54,55,56,64,65,66],[74,75,76,84,85,86,94,95,96],[17,18,19,27,28,29,37,38,39],[47,48,49,57,58,59,67,68,69],[77,78,79,87,88,89,97,98,99]]

Lambdabot varsayılan olarak Data.List ve Data.List.Split'i yükler (BlackCap'in çözümünün kutuları kontrol ettiğini sanmıyorum).

İyileştirme için fikirler

// Düzenleme: Ben berbat :) :)
Düzenleme: BlackCap tarafından kaydedilen 3 bayt


Haklısın, satırları ve sütunları kontrol etmenin yeterli olmadığını fark etmedim ..
BlackCap

peki, ben de
batırdım

1
Sen yerini alabilir (map sort)ile(sort<$>)
blackcap

1
Ve .c$(sort<$>)<$>ile$(sort<$>)=<<
blackcap

oh benim, o 2 hatırladım gerekirdi
michi7x7


0

Clojure, 151 bayt

Oldukça uzun, ama diğerleri de öyle görünüyor. Ayrıca kümelerin birleşmesini gerektirecek requirekadar can sıkıcı bir durum olduğu için bunun yerine bir vektörler konsatifi kullandım.

Her satır ve sütunda yinelenir ve değer 1 ile 9 arasındaysa, biri satır, sütun ve 3x3 hücre için üç vektör verir. Başarı durumunda 0 döndürür nil, aksi takdirde, iki fazla karakter başarısız olduğunda 1 döndürür. Sayıları 1 - 9 arasındaki dışa döndürerek işler nilancak tamsayı olmayan değerler gibi diğer anormallikler üzerine çökecektir. Bölümler 0 - 2 olduğundan değerleri kullanmak 8ve 9hücre değerlerini satırlardan ve sütunlardan ayırmak güvenlidir .

(fn[s](if(= 243(count(set(apply concat(for[i(range 9)j(range 9)](let[v(nth(nth s i)j)q #(quot % 3)](if(<= 1 v 9)[[8 v i][9 v j][(q i)(q j)v]])))))))0))

Giriş, vektörlerin yuvalanmış bir vektörüdür (bu şekilde nthçalışır):

(def sudoku [[1 2 3 4 5 6 7 8 9]
             [4 5 6 7 8 9 1 2 3] 
             [7 8 9 1 2 3 4 5 6] 
             [2 3 1 5 6 4 8 9 7] 
             [5 6 4 8 9 7 2 3 1] 
             [8 9 7 2 3 1 5 6 4] 
             [3 1 2 6 4 5 9 7 8] 
             [6 4 5 9 7 8 3 1 2] 
             [9 7 8 3 1 2 6 4 5]])

Ungolfed:

(defn f [s]
  (->> (for [i (range 9) j (range 9)]
         (let [v (-> s (nth i) (nth j)) q #(quot % 3)]
           (if (<= 1 v 9)
             [[:row v i] [:col v j] [:cell [(q i) (q j)] v]])))
    (apply concat)
    set
    count
    (#(if (= 243 %) :pass :fail))))

0

PHP, 196 190 bayt

while($i<9){for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];for(;$k<3;)$c.=substr($a[++$k+$i-$i%3],$i%3*3,3);if(($u=count_chars)($a[++$i],3)<($d=123456789)|$u($b,3)<$d|$u($c,3)<$d)die(1);}

Program 9 ayrı komut satırı argümanı alır (ızgaradaki her satır için bir rakam dizesi); geçersiz için (hata)
ile çıkar, geçerli için (ok).10

İle koş php -nr '<code>' <row1> <row2> ....

Yıkmak

while($i<9)
{
    for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];  // column to string
    for(;$k++<3;)$c.=substr($a[$i-$i%3+$k],$i%3*3,3);   // sub-grid to string
    if(($u=count_chars)($a[++$i],3)<($d=123456789)      // check row
        |$u($b,3)<$d                                    // check column
        |$u($c,3)<$d                                    // check sub-grid
    )die(1);                                            // test failed: exit with 1
}

açıklama

count_charsBir dizgede karakterleri sayar ve genellikle anahtarlar gibi ascii kodları ve bir değer olarak karakter sayımlarını içeren bir dizi oluşturur; ancak 3mode parametresi olarak karakterlerden sıralanmış bir dize oluşturur; ve bu istenen rakam ile sayı ile kolayca karşılaştırılabilir.

Karşılaştırma sadece kopyaları kontrol etmekle kalmaz aynı zamanda geçersiz karakterleri de kontrol eder. Ve sadece bunu gerektirir <, !=çünkü bu sayısal bir karşılaştırma değil: PHP, dizeyi olabildiğince bir sayı olarak yorumlayacaktır. 123e56789,0x3456789 veya benzerleri görünmüyor, çünkü karakterler sıralanıyor; ve rakamı eksik olan herhangi bir tam sayı , elbette ki 123456789... ' dan daha küçüktür .23456789.

$a=$argvbir bayt $d=123456789kaydeder, dokuz $u=count_charskaydeder ve 13 kaydeder.


-1

C # - 306 298 288 karakter

Kontrol fonksiyonunu çağırmak için aşağıdaki Konsol programı kullanılmıştır;

static void Main(string[] args)
    {
        int[,] i={{1,2,3,4,5,6,7,8,9},
             {4,5,6,7,8,9,1,2,3},
             {7,8,9,1,2,3,4,5,6},
             {2,3,1,5,6,4,8,9,7},
             {5,6,4,8,9,7,2,3,1},
             {8,9,7,2,3,1,5,6,4},
             {3,1,2,6,4,5,9,7,8},
             {6,4,5,9,7,8,3,1,2},
             {9,7,8,3,1,2,6,4,5}
            };

            Console.Write(P(i).ToString());
    }

Tüm bunlar diziyi ilklendirmek ve kontrol fonksiyonuna P aktarmaktır.

Kontrol işlevi aşağıdaki gibidir (Golf biçiminde);

private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];for(int p=0;p<9;p++){r[p]=45;c[p]=45;g[p]=45;}for(int y=0;y<9;y++){for(int x=0;x<9;x++){r[y]-=i[x,y];c[x]-=i[x,y];int k=(x/3)+((y/3)*3);g[k]-=i[x,y];}}for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}

Ya da tamamen ortaya konmuş formda;

    private static int P(int[,] i)
    {
        int[] r = new int[9],c = new int[9],g = new int[9];
        for (int p = 0; p < 9; p++)
        {
            r[p] = 45;
            c[p] = 45;
            g[p] = 45;
        }

        for (int y = 0; y < 9; y++)
        {
            for (int x = 0; x < 9; x++)
            {
                r[y] -= i[x, y];

                c[x] -= i[x, y];

                int k = (x / 3) + ((y / 3) * 3);
                g[k] -= i[x, y];
            }
        }

        for (int p = 0; p < 9; p++)
            if (r[p] > 0 | c[p] > 0 | g[p] > 0) return 1;

        return 0;
    }

Bu, tüm sütunların, satırların ve alt ızgaraların 45'e kadar eklemesi gerektiği fikrini kullanır. Giriş dizisi boyunca çalışır ve her bir konumun değerini satır, sütun ve alt ızgaradan çıkarır. Tamamlandıktan sonra, satır, sütun veya alt ızgaraların hiçbirinin hala bir değeri olmadığını kontrol eder.

İstendiği gibi, dizi geçerli bir Sudoku çözümü ve sıfır olmayan (1) değilse, 0 döndürür.


Bunun private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];yerine bazı karakterleri kaydedebileceğinizi düşünüyorum . (Yakın köşeli ayraçtan sonra boşluğun kaldırıldığına dikkat edin ].) Ayrıca, emin değilim ama sanırım ondan kurtulabilirsiniz private static.
user12205

Ayrıca, son kısım için, C'de bazı parantezleri çıkarabiliriz for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}, yani C # ile çalışıp çalışmadığından emin değiliz. (Aslında C # bilmiyorum)
user12205

@ ace - Önerilerinize dayanarak birkaç geliştirme yaptım. Şimdi aşağıya 298 karakter.
Will

@Ace yorumlarına göre 10 karakter daha kesildi.
Will

1
5 sayı ile dolu bir dizide ne olur? Tüm satırlar, sütunlar ve kareler 45'e kadar ekler.
Level River St
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.