Buat solusi sudoku CHECKER

21

Buat CHECKER solusi Sudoku

Ada banyak sekali SOLOTER Sudoku di sini, tapi saya ingin Anda membuat CHECKER solusi sekecil mungkin secara manusiawi (kode-golf).

  • Entri yang valid akan dapat mengambil array 9x9 sebagai argumen (disahkan oleh referensi, diserialisasi pada baris perintah, atau bagaimanapun Anda ingin mengambilnya) atau menerima file input sembilan baris dari sembilan angka untuk kisi terakhir . Lihat contoh input di bawah ini.

  • Masukan yang valid harus berupa angka dasar-10 (1-9)

  • Posisi yang hilang, kosong, ekstra, non-numerik, atau posisi dengan angka di luar 1-9 harus ditolak sebagai input yang tidak valid dengan mengembalikan hasil yang tidak nol, mencetak kesalahan, atau keduanya.

  • Program Anda perlu menguji apakah setiap angka muncul satu kali per kolom, sekali per baris, dan sekali per 3x3 sub-grid. Jika lolos, kembalikan "0" dan jika tidak, kembalikan hasil yang tidak nol.

  • Penggunaan sumber daya eksternal (situs web, dll.) Harus dihindari.

  • Jika solusi Anda adalah program yang berdiri sendiri, keluar dengan status keluar dari, atau mencetak, "0" atau tidak nol untuk "Pass" atau "Fail", masing-masing, ok.

Biarkan jawaban terkecil menang!

Contoh Input:

c array:

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}
                };

mengajukan:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

9 sub-grid:

+---+---+---+
|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|
+---+---+---+
David Wilkins
sumber

Jawaban:

5

GolfScript, 39 karakter

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

Dibutuhkan array array sebagai input (lihat contoh online ) dan output 0jika grid yang valid.

Penjelasan singkat tentang kode

.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
Howard
sumber
Saya suka bahwa output non-nol kode Anda lebih berarti daripada hanya 1atau-1
David Wilkins
Saya benar-benar menyukai jawaban Anda, tetapi pada akhirnya saya memilih untuk tidak pergi dengan solusi skrip golf. Saya sangat berharap Anda mengerti
David Wilkins
2
@ DavidvidWilkins Sebenarnya saya tidak mengerti - Anda membuat aturan (!) Dan tidak menyatakan di mana saja bahwa GolfScript tidak diizinkan.
Howard
Maksud Anda sepenuhnya valid ... sebenarnya saya tidak punya alasan untuk tidak memilih jawaban Anda. Dimainkan dengan baik
David Wilkins
10

Python, 103

Saya benci sudoku.

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))))

Cara kerjanya: setiap baris, kolom, dan blok harus memiliki masing-masing angka dari 1 hingga 9. Jadi untuk masing-masing 0 <= i, j < 9, sel i,jdi blok 3*floor(i/3) + floor(j/3). Dengan demikian, ada 243 persyaratan yang harus dipenuhi. Saya membuat masing-masing persyaratan tuple di ((item index,item type number),symbol)mana item indexangka antara 0 dan 8 (inklusif), item type numberadalah 0,1, atau 2 untuk menunjukkan baris, kolom atau blok masing-masing, dan symbolmerupakan entri b[i][j].

Sunting: Saya keliru tidak memeriksa entri yang valid. Sekarang saya lakukan.

stan
sumber
Program Anda harus menampilkan 0jika solusinya lewat, tidakTrue
David Wilkins
@ Davidvidil apa persyaratan aneh. Tetap.
Stanby
Anda mendapatkan suara saya hanya untuk cara Anda memulai jawaban Anda: D
Teun Pronk
9

APL (46)

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

Ini membutuhkan matriks 9-oleh-9. Contohnya bisa dimasukkan di TryAPL seperti:

     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

Penjelasan:

  • ↓⍉⍵: dapatkan kolom ,
  • ↓⍵: dapatkan baris ,
  • 3/3⌿3 3⍴Z←⍳9: Membuat matriks 3-by-3 yang berisi angka-angka 1untuk 9, maka rangkap tiga masing-masing nomor di kedua arah, memberikan matriks 9-by-9 dengan angka 1untuk 9menunjukkan masing-masing kelompok,
  • Z∘.=: Untuk setiap nomor 1untuk 9, membuat bitmask untuk kelompok tertentu,
  • /∘(,⍵)¨: dan topeng dengan masing-masing, memberikan kelompok .
  • ∊∘Z¨: Untuk setiap sub-array, melihat apakah mengandung angka 1untuk 9,
  • ∧/,↑: ambil yang logis anddari semua angka ini bersama-sama.
marinus
sumber
+1 Bagus! Tetapi kelompok 3 × 3 dapat bermain golf lagi. Misalnya ini ↓9 9⍴1 3 2⍉3 3 9⍴⍵setara dengan /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9tetapi cukup pendek. Saya yakin bahkan ada formula yang lebih pendek.
Tobia
Selain itu, Anda dapat menggabungkan matriks dengan dimensi 1 dan melakukan pemisahan tunggal di akhir:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia
Ada bug: kode ∊∘Z¨ini menguji apakah setiap sub-array (baris, kolom atau blok) hanya terbuat dari angka 1 hingga 9. Itu tidak menguji apakah semua angka diwakili. Anda perlu melakukan sesuatu seperti Z∘.∊yang menguji bahwa setiap angka dalam Z terkandung dalam setiap sub-array.
Tobia
Dan ini ∧/,↑bisa disingkat ∧/∊. Aku sudah selesai, sudah selesai! ;-)
Tobia
Sangat kompak, tetapi Anda melewatkan satu titik kritis yang dapat saya lihat langsung:If it passes, return "0" and if not, return a non-zero result.
David Wilkins
5

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

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;}

(Ubah booleanke booluntuk C #)

Diformat:

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;
}

Metode ini menciptakan sebuah array udengan 27 bitmask, mewakili digit yang ditemukan di sembilan baris, kolom, dan kotak.

Itu kemudian beralih di atas semua sel, melakukan operasi 1 << a[x][y]untuk membuat bitmask yang mewakili digit dan OR kolomnya, baris dan bitmask persegi dengannya.

Itu kemudian beralih ke semua 27 bitmasks, memastikan bahwa mereka semua menambahkan hingga 27594 (1022 * 9, 1022 menjadi bitmask untuk semua digit 1-9 yang hadir). (Catatan yang yberakhir sebagai 27603 karena sudah mengandung 9 mengikuti loop ganda.)

Sunting: Tidak sengaja tertinggal dalam %3yang tidak lagi diperlukan.

Sunting 2: Terinspirasi oleh komentar Bryce Wagner, kode ini telah dikompres lebih sedikit.

Pemburu kecil
sumber
Algoritma yang hampir sama dalam karakter C # 149 (tetapi hanya jika Linq diizinkan): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; sementara (x ++ <(y = 9)) sementara (y> 0) {j = 1 << a [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 memang akan berguna. Namun, solusi saya adalah untuk Java dengan C # menjadi renungan (bahkan tidak disebutkan dalam posting asli) dan dengan demikian prioritas yang lebih rendah. Saya juga menggunakan array satu dimensi untuk kekompakan di awal sebelum memutuskan menentangnya (seperti contoh menggunakan array dua dimensi). Namun demikian, kode Anda memberi saya beberapa ide tentang bagaimana beberapa byte lagi dapat dicukur. :)
Smallhacker
3

python = 196

Bukan yang paling golf, tetapi idenya ada di sana. Set sangat berguna.

Naik:

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)
qwr
sumber
s / {1,2,3,4,5,6,7,8,9} / set (rentang (1,10)) / menyimpan 3 karakter.
MatrixFrog
Dalam Python 3.5 Anda dapat menggunakan n={*range(1,10)}, tapi itu lebih baru daripada tantangannya. Alih-alih gunakan set(range(1,10))seperti kata MatrixFrog.
mbomb007
3

Java - 385 306 328 260 karakter

Sunting: Saya dengan bodohnya salah membaca instruksi bahwa jawabannya harus merupakan program yang lengkap. Karena itu bisa menjadi fungsi yang valid, saya telah menulis ulang dan meminimalkan menjadi fungsi, dan menulis ulang pengenalan solusi saya dengan itu dalam pikiran.

Jadi, sebagai tantangan bagi diri saya, saya pikir saya akan mencoba membuat pemeriksa solusi Java terkecil.

Untuk mencapai ini saya berasumsi bahwa teka-teki sudoku akan diteruskan sebagai array multidimensi java, seperti:

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}});

Kemudian, kami memiliki pemecah yang sebenarnya, yang mengembalikan "0" jika solusi yang valid, "1" jika tidak.

Sepenuhnya 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;}

Dapat dibaca:

    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;
    }

Jadi bagaimana cara kerjanya? Saya pada dasarnya hanya membuat basis angka saya sendiri dengan resolusi yang cukup di setiap digit yang saya hanya perlu melakukan tiga perbandingan numerik setelah melewati teka-teki sekali untuk mengetahui apakah itu valid. Saya memilih basis 49 untuk masalah ini, tetapi setiap basis yang lebih besar dari 45 akan cukup.

Contoh (mudah-mudahan) jelas: bayangkan bahwa setiap "baris" dalam teka-teki sudoku adalah satu digit dalam nomor basis-49. Kami akan merepresentasikan setiap digit pada nomor basis-49 sebagai angka dasar-10 dalam vektor untuk kesederhanaan. Jadi, jika semua baris "benar", kami mengharapkan nomor base-49 berikut (sebagai vektor base-10):

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

atau dikonversi ke nomor basis-10 tunggal: 1526637748041045

Ikuti logika serupa untuk semua kolom, dan sama untuk "sub-grid". Nilai apa pun yang ditemukan dalam analisis akhir yang tidak sama dengan "angka ideal" ini berarti solusi puzzle tidak valid.

Edit untuk mengatasi kerentanan semua-5 dan masalah terkait lainnya: Saya menambahkan nomor basis-49 keempat, berdasarkan gagasan bahwa harus ada 9 dari setiap angka dalam setiap puzzle. Jadi, saya menambahkan 5 ke setiap digit dalam nomor basis-49 untuk setiap kemunculan nomor basis-10 yang mewakili indeks digit. Contoh, jika ada 10 9 dan 9 8, 9 7, 8 6, dan 9 dari yang lainnya, Anda akan mendapatkan nomor basis-49 (sebagai vektor basis-10 ukuran 10 untuk menangani overflow):

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

Yang akan gagal jika dibandingkan dengan nomor base-49 "ideal" kami.

Solusi saya memanfaatkan solusi matematika ini, untuk menghindari sebanyak mungkin perulangan dan perbandingan. Saya hanya menggunakan longnilai untuk menyimpan setiap nomor base-49 sebagai nomor base-10 dan menggunakan array pencarian untuk mendapatkan "faktor" untuk setiap digit base-49 selama perhitungan nilai kolom / baris / subgrid perhitungan.

Karena Java tidak dirancang untuk ringkas, berhati-hati dalam konstruksi matematika adalah satu-satunya cara saya pikir saya bisa membangun pemeriksa ringkas.

Biarkan aku tahu apa yang Anda pikirkan.

ProgrammerDan
sumber
1
Sebenarnya, ini menderita dari kerentanan yang sama yang disebutkan oleh @ steve-verrill - semua 5's, atau set angka yang berjumlah 45, akan "menipu" pemecah masalah. Saya akan merevisinya. Saya punya ide bagaimana untuk mengalahkan itu.
ProgrammerDan
Saya telah membahas kerentanan ini dalam pembaruan terakhir saya. Sekarang kasus itu sudah diatasi, dan semua yang lainnya dari jenisnya. Pada dasarnya, itu adalah pengawasan serius untuk tidak berurusan dengan "jumlah" dari setiap jenis basis-10 digit. Saya sekarang melakukan pemeriksaan itu secara langsung, tetapi menggunakan pendekatan matematika yang sama (nomor base-49).
Programmer Dan
Dan, terima kasih atas pengakuannya. Saya melihatnya dan bertanya-tanya mengapa saya tidak diberi tahu, tetapi saya melihat Anda mencoret nama saya. Ini sepertinya membingungkan sistem. Cukup hapus ruangnya. Saya akan mempertimbangkan untuk mengubah cara nama saya ditampilkan.
Level River St
Ahha, itu menjelaskannya. Terima kasih @steveverrill - Saya masih terbiasa dengan cara stackexchange melakukan sesuatu. Yang mengatakan, eksploitasi singkat Anda dari prinsip sum-45 dinyatakan dengan cemerlang. Membuat solusi saya lebih lama untuk mengatasinya, tapi itulah hidup!
ProgrammerDan
3

R 145

function(x)colSums(do.call(rbind,lapply(list(R<-row(b<-matrix(1,9,9)),C<-col(b),(R-1)%/%3+1+3*(C-1)%/%3),sapply,`==`,1:9))%*%c(2^(x-1))==511)==27

Kode de-golfed (kurang lebih) dapat ditemukan di sini /programming//a/21691541/1201032 .

flodel
sumber
dapatkah Anda memberikan contoh kerja di situs seperti r-fiddle? r-fiddle.org/#
David Wilkins
3

Haskell (Lambdabot), 65 byte

k x=and$(all$([1..9]==).sort)<$>[x,transpose x,join$chunksOf 3 x]
BlackCap
sumber
2

Perl, 193 byte

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)

Input diharapkan dalam bentuk array:

@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]
);

Kode keluar adalah 0, jika @amerupakan solusi, jika 1tidak dikembalikan.

Versi tidak disatukan:

@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);

Masing-masing dari 9 baris, 9 kolom dan 9 sub array dimasukkan ke dalam array yang diurutkan dan diperiksa, apakah cocok dengan array (1..9). Jumlahnya $rbertambah untuk setiap pertandingan yang berhasil yang harus berjumlah hingga 27 untuk solusi yang valid.

Heiko Oberdiek
sumber
2

J 52 54

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

Membawa argumen yang ditempel di baris perintah, diakhiri dengan a) sebagai:

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
)

Mengembalikan 1 jika lulus, 0 jika tidak.

Secara internal, ini mengkonversi grid 9x9 menjadi grid 3x3x3x3, dan melakukan beberapa permutasi pada sumbu untuk mendapatkan unit yang diinginkan (baris, garis, dan kotak) dalam 2 dimensi terakhir.

Setelah melakukan itu, diperiksa bahwa setiap unit memiliki 9 nilai unik.

Mungkin jauh dari sempurna, tetapi sudah mengalahkan mayoritas ;-)

jpjacobs
sumber
Pada pandangan pertama, Anda telah ditangkap oleh persyaratan yang sama seperti yang lain .... Pengembalian Anda harus dibalik ... 0 untuk lulus, bukan nol untuk gagal
David Wilkins
0 untuk lulus adalah idiot. Ada alasan Boole memilih 1 untuk true dan 0 untuk false. Tapi kamu benar. Menambahkan 2 karakter.
jpjacobs
Anggap saja sebagai status keluar, bukan nilai boolean
David Wilkins
Saya memilih jawaban Anda karena itu berfungsi. Anda mengikuti aturan dan program Anda sangat singkat. Terima kasih!
David Wilkins
Ya saya berselingkuh ... Sebenarnya saya tidak bisa membenarkan tidak memilih jawaban Golfscript yang lebih pendek dari Anda ... Tapi pujian untuk tempat ke-2
David Wilkins
2

Mathematica, 84 79 karakter

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

Contoh:

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

alephalpha
sumber
Contoh keluaran ketiga Anda: Apakah 3selalu menunjukkan input yang tidak valid, atau adakalanya respons terhadap solusi yang gagal?
David Wilkins
2

Javascript ES6, 150 karakter

Mengambil input sebagai string 81-char tanpa pembatas.

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

Fungsi kembali nullsebagai jawaban negatif dan sebuah array dengan string asli di elemen pertama sebagai positif. Dapat berubah menjadi bool dengan menambahkan!! fungsi awal.

Tes (lihat tantangan terkait untuk lebih banyak detais):

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))
Qwertiy
sumber
Itu satu regex konyol ... Kerja luar biasa.
ETHproduk
2

R, 63 50 byte

Mengasumsikan input m adalah matriks angka 9x9.

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

Saya benar bahwa golf lebih lanjut adalah mungkin.

Penjelasan:

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

Ambil m, dan untuk setiap baris, terapkan matchfungsi. Kami menentukan argumen lebih lanjut x=1:9untuk diteruskan match. xadalah argumen posisi pertama default, dan oleh karena itu setiap baris ditempatkan di posisi argumen kedua, yaitu table. Fungsi matchmencari instance xin table. Dalam hal ini, maka, ia mencari 1:9(angka 1 hingga 9) di setiap baris. Untuk masing-masing 1:9, itu akan kembaliTRUE (atauFALSE ) jika nomor itu ditemukan (atau tidak).

Jadi, ini menghasilkan serangkaian 81 nilai boolean.

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

Ulangi langkah di atas untuk setiap kolom input.

all(                                             )

Akhirnya, allperiksa apakah setiap elemen dari daftar boolean adalah TRUE. Ini akan menjadi kasus jika dan hanya jika solusinya benar (yaitu setiap angka 1:9hanya ada satu kali di setiap kolom dan setiap baris).

Pendekatan lama:

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

Dibutuhkan setiap baris, mengurutkannya, dan kemudian membandingkannya [1, 2, ... 9]. Baris yang benar harus sama persis. Kemudian ia melakukan hal yang sama untuk setiap kolom. Secara total, kita harus memiliki 162 pencocokan tepat, yang merupakan bagian terakhir untuk memeriksa. Kemungkinan ada beberapa ruang untuk bermain golf lebih lanjut di sini ...

rturnbull
sumber
Sepertinya Anda memeriksa kolom dan baris, tetapi tidak untuk kotak ...
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]]]

Fungsi vadalah fungsi untuk memanggil. Ini bekerja dengan mendapatkan perbedaan dari setiap baris, kolom dan blok terhadap daftar [1..9]dan merangkum panjang daftar perbedaan tersebut.

Demo menggunakan contoh Sudoku:

*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
TimWolla
sumber
1

Javascript - 149 Karakter

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]

Mengharapkan array aada dan membuat variabel ountuk output yang 0sukses dan bukan nol sebaliknya.

Bekerja dengan memeriksa bahwa jumlah posisi di mana setiap nilai terjadi untuk setiap baris, kolom, dan 3 * 3 kotak sama dengan 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).

Pengujian

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]
  ];

Memberi 'o = 0'

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]
  ];

(2 digit terakhir ditukar)

Memberi 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]
  ];

Memberi o=-284

MT0
sumber
1

Haskell, 121 130 127 byte (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]

menggunakan:

-- 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 memuat Data.List dan Data.List.Split secara default (Saya tidak berpikir solusi BlackCap memeriksa kotak).

Gagasan untuk perbaikan disambut

// Edit: Saya mengacaukan :)
// Edit: 3 byte disimpan oleh BlackCap

michi7x7
sumber
Anda benar, saya gagal memperhatikan bahwa memeriksa baris dan kolom tidak cukup ..
BlackCap
baik, saya juga mengacaukan :)
michi7x7
1
Anda dapat menggantinya (map sort)dengan(sort<$>)
BlackCap
1
Dan .c$(sort<$>)<$>dengan$(sort<$>)=<<
BlackCap
oh my, seharusnya ingat 2
michi7x7
1

05AB1E , 36 bytes | NoN-Competing |

|©vy3ô})3ôøvyJvyê}}®øvyê}®vyê})êžh¦Q

Cobalah online!

1 itu benar, yang lain salah.

Guci Gurita Ajaib
sumber
0

Clojure, 151 byte

Cukup lama, tetapi yang lain tampaknya juga. Juga mengganggu bahwa set himpunan membutuhkan require, jadi saya menggunakan vektor sebagai gantinya.

Ulangi setiap baris dan kolom dan jika nilainya antara 1 dan 9, ia memancarkan tiga vektor, satu untuk baris, col, dan sel 3x3. Mengembalikan 0 pada kesuksesan dan nilsebaliknya, dengan dua karakter tambahan dapat mengembalikan 1 pada gagal. Menangani angka di luar 1 - 9 dengan mengembalikan niltetapi akan crash pada anomali lain seperti nilai non-integer. Quotients adalah 0 - 2 sehingga aman untuk menggunakan nilai 8dan 9untuk membedakan nilai sel dari baris dan kolom.

(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))

Input adalah vektor vektor bersarang (sehingga nthberfungsi):

(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]])

Tidak Disatukan:

(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))))
NikoNyrh
sumber
0

PHP, 196 190 byte

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 mengambil 9 argumen baris perintah yang terpisah (satu string angka untuk setiap baris grid);
keluar dengan 1(kesalahan) untuk tidak valid, 0(ok) untuk valid.

Jalankan dengan php -nr '<code>' <row1> <row2> ....

kerusakan

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
}

penjelasan

count_charsmenghitung karakter dalam string dan biasanya membuat array dengan kode ascii sebagai kunci dan karakter dihitung sebagai nilai; tetapi dengan 3sebagai parameter mode, itu menciptakan string yang diurutkan dari karakter; dan itu dapat dengan mudah dibandingkan dengan angka dengan angka yang diinginkan.

Perbandingan tidak hanya memeriksa duplikat, tetapi juga mencakup pemeriksaan untuk karakter yang tidak valid. Dan itu hanya memerlukan <, bukan !=, karena ini adalah perbandingan numerik: PHP akan mengartikan string sejauh mungkin. 123e56789, 0x3456789atau yang serupa tidak dapat muncul, karena karakter diurutkan; dan bilangan bulat murni dengan digit yang hilang lebih kecil dari123456789 ... dan .23456789juga, tentu saja.

$a=$argvmenyimpan satu byte, $d=123456789menyimpan sembilan dan $u=count_charsmenyimpan 13.

Titus
sumber
-1

C # - 306 298 288 karakter

Program Konsol berikut digunakan untuk memanggil fungsi pemeriksaan;

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());
    }

Semua ini dilakukan adalah menginisialisasi array dan meneruskannya ke fungsi pemeriksaan P.

Fungsi pemeriksaan adalah seperti di bawah ini (dalam bentuk Golf);

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;}

Atau dalam bentuk yang ditata sepenuhnya;

    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;
    }

Ini menggunakan gagasan bahwa semua kolom, baris, dan sub-grid harus berjumlah hingga 45. Ia bekerja melalui array input dan mengurangi nilai setiap posisi dari baris, kolom, dan sub-grid itu. Setelah selesai maka periksa bahwa tidak ada baris, kolom atau sub-grid yang masih memiliki nilai.

Seperti yang diminta mengembalikan 0 jika array adalah solusi Sudoku yang valid dan bukan nol (1) di mana tidak.

Akan
sumber
Saya pikir Anda dapat menyimpan beberapa karakter dengan menggunakan private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];sebagai gantinya. (Perhatikan penghapusan ruang setelah braket kotak dekat ].) Juga, saya tidak yakin tapi saya pikir Anda dapat menyingkirkan private static.
user12205
Juga, untuk bagian terakhir, di C kita dapat menghapus beberapa kawat gigi yaitu for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}, tidak yakin apakah itu berfungsi di C #. (Saya sebenarnya tidak tahu C #)
user12205
@ace - Saya telah membuat beberapa perangkat tambahan berdasarkan saran Anda. Sekarang turun ke 298 karakter.
Will
Memotong 10 karakter lagi berdasarkan komentar dari @ace.
Will
1
Apa yang terjadi dengan array yang penuh dengan angka 5? Semua baris, kolom, dan bujur sangkar bertambah hingga 45.
Level River St