Inilah saatnya untuk memulai upaya berbahaya untuk mengalahkan Intelejen Inggris. Tujuan dari tantangan ini adalah untuk menulis kode terpendek yang akan menyelesaikan Nonogram.
Apa itu Nonogram?
Aturannya sederhana. Anda memiliki kotak kotak, yang harus diisi hitam atau kosong. Di sebelah setiap baris kisi dicantumkan panjang garis kotak hitam pada baris itu. Di atas setiap kolom tercantum panjang jalur kotak hitam di kolom itu. Tujuan Anda adalah untuk menemukan semua kotak hitam. Dalam jenis teka-teki ini, angka-angka adalah bentuk tomografi diskrit yang mengukur berapa banyak garis kotak diisi yang ada di setiap baris atau kolom. Misalnya, petunjuk "4 8 3" akan berarti ada empat, delapan, dan tiga kotak yang diisi, dalam urutan itu, dengan setidaknya satu kotak kosong di antara kelompok-kelompok yang berurutan. [ 1 ] [ 2 ]
Jadi solusi untuk Nonogram di atas adalah:
Detail Implementasi
Anda dapat memilih untuk mewakili Nonogram namun Anda ingin dan mengambilnya sebagai input dengan cara apa pun yang Anda anggap cocok untuk bahasa Anda. Sama berlaku untuk output. Tujuan dari tantangan ini adalah benar-benar menyelesaikan pekerjaan; jika Anda dapat menyelesaikan nonogram dengan output apa pun yang diberikan oleh program Anda, itu valid. Satu peringatan adalah Anda tidak dapat menggunakan pemecah online :)
Masalah ini sangat menantang secara algoritmik (np-selesai) karena tidak ada solusi yang sepenuhnya efisien untuk itu dan karena itu, Anda tidak akan dihukum karena tidak dapat memecahkan yang lebih besar, meskipun jawaban Anda akan sangat dihargai jika itu mampu menangani kasus besar (lihat bonus). Sebagai patokan, solusi saya berfungsi hingga 25x25 dalam waktu 5-10 detik. Untuk memungkinkan fleksibilitas di antara berbagai bahasa, solusi yang membutuhkan waktu kurang dari 5 menit untuk nonogram 25x25 cukup baik.
Anda dapat mengasumsikan sebuah teka-teki dalam bentuk selalu non-persegi NxN.
Anda dapat menggunakan pembuat puzzle nonogram online ini untuk menguji solusi Anda.
Mencetak gol
Anda, tentu saja, bebas menggunakan bahasa apa pun yang Anda inginkan dan karena ini adalah kode golf, entri akan diurutkan dalam urutan: accuracy -> length of code -> speed.
Namun, jangan berkecil hati dengan bahasa kode golf, jawaban dalam semua bahasa yang menunjukkan upaya untuk bermain golf dengan cara yang menarik akan terbalik!
Bonus
Saya sebenarnya belajar tentang Nonogram dari kartu Natal kriptografis yang dirilis oleh Intelejen Inggris di sini . Bagian pertama pada dasarnya adalah Nonogram 25x25 besar. Jika solusi Anda dapat menyelesaikan ini, Anda akan mendapatkan pujian :)
Untuk membuat hidup Anda lebih mudah dalam hal entri data, saya telah menyediakan bagaimana saya mewakili data untuk teka-teki khusus ini untuk Anda gunakan secara gratis. 25 baris pertama adalah petunjuk baris, diikuti oleh garis pemisah '-', diikuti oleh 25 baris petunjuk col, diikuti oleh garis pemisah '#', dan kemudian representasi dari grid dengan petunjuk kotak diisi.
7 3 1 1 7
1 1 2 2 1 1
1 3 1 3 1 1 3 1
1 3 1 1 6 1 3 1
1 3 1 5 2 1 3 1
1 1 2 1 1
7 1 1 1 1 1 7
3 3
1 2 3 1 1 3 1 1 2
1 1 3 2 1 1
4 1 4 2 1 2
1 1 1 1 1 4 1 3
2 1 1 1 2 5
3 2 2 6 3 1
1 9 1 1 2 1
2 1 2 2 3 1
3 1 1 1 1 5 1
1 2 2 5
7 1 2 1 1 1 3
1 1 2 1 2 2 1
1 3 1 4 5 1
1 3 1 3 10 2
1 3 1 1 6 6
1 1 2 1 1 2
7 2 1 2 5
-
7 2 1 1 7
1 1 2 2 1 1
1 3 1 3 1 3 1 3 1
1 3 1 1 5 1 3 1
1 3 1 1 4 1 3 1
1 1 1 2 1 1
7 1 1 1 1 1 7
1 1 3
2 1 2 1 8 2 1
2 2 1 2 1 1 1 2
1 7 3 2 1
1 2 3 1 1 1 1 1
4 1 1 2 6
3 3 1 1 1 3 1
1 2 5 2 2
2 2 1 1 1 1 1 2 1
1 3 3 2 1 8 1
6 2 1
7 1 4 1 1 3
1 1 1 1 4
1 3 1 3 7 1
1 3 1 1 1 2 1 1 4
1 3 1 4 3 3
1 1 2 2 2 6 1
7 1 3 2 1 1
#
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Dan ini adalah versi yang sedikit berbeda untuk kenyamanan Anda; tuple yang dipisahkan koma (baris, col) di mana setiap elemen adalah daftar daftar.
([[7, 3, 1, 1, 7],
[1, 1, 2, 2, 1, 1],
[1, 3, 1, 3, 1, 1, 3, 1],
[1, 3, 1, 1, 6, 1, 3, 1],
[1, 3, 1, 5, 2, 1, 3, 1],
[1, 1, 2, 1, 1],
[7, 1, 1, 1, 1, 1, 7],
[3, 3],
[1, 2, 3, 1, 1, 3, 1, 1, 2],
[1, 1, 3, 2, 1, 1],
[4, 1, 4, 2, 1, 2],
[1, 1, 1, 1, 1, 4, 1, 3],
[2, 1, 1, 1, 2, 5],
[3, 2, 2, 6, 3, 1],
[1, 9, 1, 1, 2, 1],
[2, 1, 2, 2, 3, 1],
[3, 1, 1, 1, 1, 5, 1],
[1, 2, 2, 5],
[7, 1, 2, 1, 1, 1, 3],
[1, 1, 2, 1, 2, 2, 1],
[1, 3, 1, 4, 5, 1],
[1, 3, 1, 3, 10, 2],
[1, 3, 1, 1, 6, 6],
[1, 1, 2, 1, 1, 2],
[7, 2, 1, 2, 5]],
[[7, 2, 1, 1, 7],
[1, 1, 2, 2, 1, 1],
[1, 3, 1, 3, 1, 3, 1, 3, 1],
[1, 3, 1, 1, 5, 1, 3, 1],
[1, 3, 1, 1, 4, 1, 3, 1],
[1, 1, 1, 2, 1, 1],
[7, 1, 1, 1, 1, 1, 7],
[1, 1, 3],
[2, 1, 2, 1, 8, 2, 1],
[2, 2, 1, 2, 1, 1, 1, 2],
[1, 7, 3, 2, 1],
[1, 2, 3, 1, 1, 1, 1, 1],
[4, 1, 1, 2, 6],
[3, 3, 1, 1, 1, 3, 1],
[1, 2, 5, 2, 2],
[2, 2, 1, 1, 1, 1, 1, 2, 1],
[1, 3, 3, 2, 1, 8, 1],
[6, 2, 1],
[7, 1, 4, 1, 1, 3],
[1, 1, 1, 1, 4],
[1, 3, 1, 3, 7, 1],
[1, 3, 1, 1, 1, 2, 1, 1, 4],
[1, 3, 1, 4, 3, 3],
[1, 1, 2, 2, 2, 6, 1],
[7, 1, 3, 2, 1, 1]])
sumber
s=[].fill([].fill(0,0,25),0,25);s[3][3]=s[3][4]=s3[3][12]=s3[3][13]=s3[3][21]=s[8][6]=s[8][7]=s[8][10]=s[8][14]=s[8][15]=s[8][18]=s[16][6]=s[16][11]=s[16][16]=s[16][20]=s[21][3]=s[21][4]=s[21][9]=s[21][10]=s[21][15]=s[21][20]=s[21][21]=1;
Jawaban:
Brachylog ,
7069 byteIni mengambil daftar dua daftar (pertama indikator baris, lalu yang kolom). Setiap indikator itu sendiri adalah daftar (untuk posisi seperti
[3,1]
pada satu baris).Versi ini membutuhkan waktu sekitar 3 menit untuk menyelesaikan 5 dari 5 contoh tantangan.
Versi yang jauh lebih efisien, 91 byte
Cobalah online!
Yang ini bukan kekuatan kasar lengkap: satu-satunya perbedaan adalah bahwa yang satu ini memaksakan batasan pada nilai sel sedemikian sehingga jumlah 1s di setiap baris dan kolom cocok dengan angka yang diberikan sebagai indikator dalam input. Satu-satunya bagian brute force adalah kemudian dalam menemukan satu grid dengan batasan-batasan yang "blok" dari 1s cocok dengan apa yang diberikan sebagai indikasi.
Yang ini membutuhkan waktu sekitar 0,05 detik pada 5 dari 5 contoh tantangan. Ini masih terlalu lambat untuk kasus bonus, karena saya tidak tahu bagaimana mengekspresikan blok yang dipisahkan oleh satu atau lebih nol dalam hal kendala.
Penjelasan
Saya akan menjelaskan di bawah versi 93 byte. Satu-satunya perbedaan antara keduanya adalah panggilan ke predikat 3 yang tidak ada dalam versi 70 byte, dan penomoran predikat (karena ada satu kurang).
Predikat utama:
Predikat 1: Memaksa baris memiliki panjang tertentu, dan bahwa setiap sel adalah 0 atau 1.
Predikat 2: Batasi variabel menjadi 0 atau 1
Predikat 3: Jumlah 1 dalam daftar harus sama dengan jumlah indikator (mis. Jika indikatornya [3: 1] maka daftar harus memiliki jumlah 4)
Predikat 4: Periksa apakah blok 1 cocok dengan indikator
Predikat 5: Benar untuk blok 1s, false jika tidak
sumber
Haskell,
242 230 201 199 177 163 160 149131 byteAkhirnya di bawah 200 byte, kredit ke @Bergi. Terima kasih banyak kepada @nimi yang telah membantu mengurangi ukurannya.
Wow. Hampir setengah ukuran sekarang, sebagian karena aku tetapi terutama karena @nimi.
Fungsi sihirnya adalah
(#)
. Ia menemukan semua solusi dari nonogram yang diberikan.Ini dapat menyelesaikan semua kasus, tetapi mungkin sangat lambat, karena kompleksitasnya adalah soal
O(2^(len a * len b))
. Patokan cepat mengungkapkan 86GB dialokasikan untuk nonogram 5x5.Fakta menyenangkan: Ini bekerja untuk semua nonogram, tidak hanya yang persegi.
Bagaimana itu bekerja:
a#b
: Diberikan daftar daftar bilangan bulat yang mewakili jumlah kotak, hasilkan semua kisi (map(chunk$length b).mapM id$a>>b>>[[0,1]]
) dan filter hasilnya untuk hanya menyimpan yang valid.g
: Diberikan nonogram potensial, ini menjumlahkan jalannya 1 secara horizontal.sumber
m(chunk$l b)
danreplicate(l$a>>b)
import Data.Lists
sudah cukup, karena ekspor ulang keduanyaData.List
danData.List.Split
.Pyth,
917271 byteSuatu program yang mengambil input dari daftar bentuk di
[size, [horizontal clues], [vertical clues]]
mana setiap petunjuk adalah daftar bilangan bulat (petunjuk kosong adalah daftar kosong,[]
), dan mencetak setiap solusi, dipisahkan dengan baris baru, dalam bentuk kotak biner di mana1
berbayang dan0
adalah unshaded .Ini adalah kekuatan kasar, demikian juga kira-kira
O(2^n^2)
. Ini mulai memakan waktu yang sangat lama untuk teka-teki yang lebih besar, tetapi akan menyelesaikan setiap ukuran arbritrary diberikan waktu yang cukup.Cobalah online
Bagaimana itu bekerja
Program ini menghasilkan setiap tata letak yang mungkin dengan mengambil produk Cartesian berulang
[0, 1]
dengan panjang sama dengansize^2
. Ini kemudian dibagi menjadi potongan-potongan, memberikan daftar untuk setiap garis horizontal. Setiap baris dikode panjangnya, disaring oleh kehadiran1
dan diratakan, meninggalkan petunjuk untuk garis itu. Ini kemudian diperiksa terhadap input. Proses di atas diulang untuk transpos potongan, memeriksa garis vertikal. Jika ada klik, setiap potongan disatukan, dan potongan digabungkan digabungkan pada baris baru dan dicetak secara implisit, dengan baris baru tambahan.Terima kasih kepada @ Pietu1998 untuk beberapa tips
sumber
=ZhZ
sama dengan=hZ
, danFN
sama denganV
.Javascript (ES6),
401386333 byteIni merupakan upaya awal. Ini tidak terlalu efisien tetapi saya ingin menguji solusi menggunakan ekspresi reguler pada representasi biner dari baris dan kolom.
Misalnya, itu akan menerjemahkan petunjuk
[3,1]
ke ekspresi reguler berikut:Saat ini, versi ini tidak memperhitungkan petunjuk kuadrat. Saya mungkin akan menambahkan ini nanti.
Kode
Keluaran
Solusinya ditampilkan dalam format biner. Seperti:
Uji
Ini adalah tes sederhana pada contoh grid.
sumber
Haskell, 109 byte
Penafian: ini berasal dari jawaban @ ThreeFx . Saya membantunya mengurangi jawabannya, tetapi ia tampaknya tidak berminat untuk memasukkan peningkatan substansial terakhir saya, jadi saya mempostingnya sebagai jawaban baru.
Contoh penggunaan:
[[2],[3],[3],[3,1],[1]] # [[2],[3],[4],[2],[2]]
->[[" ## "," ### ","### ","### #"," #"]]
.Paksaan. Coba semua kombinasi
dan
#
, pisahkan potongan int#
, hitung panjangnya dan bandingkan dengan input.sumber
PHP,
751833 (720)753724726710691680682 byteSaya sangat ingin membangun kenaikan urutan khusus dan mencoba generator kartesian saya sekali lagi;
tetapi menjatuhkan kartesian demi mundur untuk memecahkan teka-teki besar lebih cepat.
$r
untuk petunjuk baris,$c
untuk petunjuk kolom dan$s
untuk petunjuk persegi.invalid argument supplied for foreach
jika tidak menemukan solusi.\n
dan hapus dua jeda baris lainnya.deskripsi
1) dari petunjuk baris
menghasilkan kemungkinan baris yang memenuhi petunjuk persegi
dan mengingat jumlah mereka untuk setiap indeks baris.
2) mundur mengikuti kombinasi baris:
Jika kombinasi memenuhi petunjuk kolom, cari lebih dalam atau kembalikan kombinasi yang berhasil,
jika tidak coba kemungkinan berikutnya untuk baris ini
3) solusi cetak
Golf terakhir memiliki dampak besar pada kinerja;
tapi saya menghapus tugas pembuatan profil untuk tolok ukur terakhir.
Ganti
$n=$n*($f=($p[$y][$i[$y]]>>$x&1)==$v)+$k=$f?:($v=!$v)||$n==$h[$z++];
dengan
if(($p[$y][$i[$y]]>>$x&1)-$v){$k=($v=!$v)||$n==$h[$z++];$n=1;}else$n++;
untuk membatalkan langkah golf terakhir.
contoh
Untuk contoh kecil (
17 hingga 21sekitar12876,75,3 ms), gunakanuntuk teka-teki natal:
5037,845,5sekitar 36 detikletakkan data dari pertanyaan ke file
christmas.nonogram
dan gunakan kode ini untuk mengimpor:kerusakan
sumber
$d
harus dalam urutan yang benar untukforeach