Di arah teman-teman kami di Puzzling.SE , teka-teki berikut diposting: Apakah teka-teki berwarna ini selalu dapat dipecahkan? oleh Edgar G. Anda dapat memainkannya di sini .
Penjelasan teka-teki
Diberi m x n
kisi dengan ubin dengan tiga warna berbeda, Anda dapat memilih dua ubin yang berdekatan , jika warnanya berbeda . Kedua ubin ini kemudian dikonversi ke warna ketiga, yaitu, satu warna yang tidak diwakili oleh dua ubin ini. Teka-teki diselesaikan jika semua ubin memiliki warna yang sama . Rupanya, seseorang dapat membuktikan bahwa teka-teki ini selalu dapat dipecahkan, jika tidak ada m
atau tidak n
dapat dibagi oleh 3.
Tentu saja, ini memohon algoritma penyelesaian. Anda akan menulis fungsi atau program yang memecahkan teka-teki ini. Perhatikan bahwa fungsi dengan 'efek samping' (yaitu, output aktif stdout
daripada dalam beberapa nilai pengembalian tipe data canggung) diizinkan secara eksplisit.
Input output
Input akan menjadi m x n
matriks yang terdiri dari bilangan bulat 1
, 2
dan 3
(atau 0
, 1
, 2
jika nyaman). Anda dapat mengambil input ini dalam format waras apa pun. Kedua m
dan n
yang >1
dan tidak habis dibagi 3. Anda mungkin menganggap teka-teki yang tidak terpecahkan
Anda kemudian akan memecahkan teka-teki. Ini akan melibatkan pemilihan berulang dua ubin yang berdekatan untuk 'dikonversi' (lihat di atas). Anda akan menampilkan dua koordinat ubin ini untuk setiap langkah yang diambil algoritma penyelesaian Anda. Ini juga mungkin dalam format output yang waras. Anda bebas memilih antara pengindeksan berbasis 0 dan 1 berdasarkan koordinat Anda, dan apakah baris atau kolom diindeks terlebih dahulu. Tolong sebutkan ini dalam jawaban Anda.
Algoritme Anda harus berjalan dalam waktu yang wajar pada kasing 8x8 asli. Brute-forcing itu sepenuhnya dilarang secara eksplisit, yaitu algoritma Anda harus berjalan di bawah O(k^[m*(n-1)+(m-1)*n])
dengan k
sejumlah langkah yang diperlukan untuk solusi. Namun solusinya tidak harus optimal. Bukti yang diberikan dalam pertanyaan yang ditautkan dapat memberi Anda ide tentang bagaimana melakukan ini (misalnya, pertama-tama lakukan semua kolom hanya menggunakan petak yang berdekatan secara vertikal, lalu lakukan semua baris)
Uji kasus
Dalam kasus uji ini, koordinatnya berbasis 1 dan baris diindeks terlebih dahulu (seperti MATLAB / Oktaf dan mungkin banyak lainnya).
Input:
[1 2]
Output: (result: all 3's)
[1 1],[1,2]
Input:
[ 1 2
3 1 ]
Output: (result: all 1's)
[1 1],[2 1] (turn left column into 2's)
[2 1],[2 2] (turn right column into 3's)
[1 1],[1 2] (turn top row into 1's)
[2 1],[2 2] (turn bottom row into 1's)
Input:
[1 2 3 2
3 2 1 1]
Output: (result: all 3's)
[1 1],[1 2]
[1 3],[1 4]
[1 2],[1 3]
[1 1],[1 2]
[1 2],[1 3]
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]
Jika diinginkan, saya dapat memposting pastebin kasus uji yang lebih besar, tapi saya pikir ini sudah cukup.
sumber
Jawaban:
Ruby, 266 byte
Lebih atau kurang hanya port dari solusi Oktaf, kecuali itu memecahkan baris terlebih dahulu bukan kolom. Input adalah larik array, dengan larik dalam menjadi baris. Keluaran bergerak adalah
[row, column, row, column]
. Suite ujiTidak diganggu dengan penjelasan
sumber
intersect
kata kunci ini sangat besar)intersect
, saya tidak tahu apakah Anda dapat memperbaiki cara saya bekerja karena Rubyfind
pada dasarnya beroperasi pada fungsi, danfunction
kata kunci Anda sama besar.find
- terima kasih! Tetap saja, tidak ada yang bisa mengalahkanmu ...Oktaf,
334313 byteKarena tantangannya mungkin tampak agak menakutkan, saya menghadirkan solusi saya sendiri. Saya tidak secara formal membuktikan bahwa metode ini bekerja (saya kira itu akan datang untuk membuktikan bahwa algoritma tidak akan pernah terjebak dalam satu lingkaran), tetapi sejauh ini ia bekerja dengan sempurna, melakukan 100x100 testcases dalam 15 detik. Perhatikan bahwa saya memilih untuk menggunakan fungsi dengan efek samping daripada yang mengembalikan semua koordinat karena itu menyelamatkan saya beberapa byte. Koordinat adalah baris-utama, berbasis 1, dan diformat sebagai
row1 col1 row2 col2
. Warna input0,1,2
karena ini bekerja lebih baik denganmod
, dengan biaya harus menggunakannumel
daripadannz
. Versi golf: Edit: menyimpan beberapa byte lagi dengan menggunakan teknik dari jawaban Kevin Lau.Contoh GIF dari algoritma penyelesaian:
Versi tidak disatukan:
sumber
Lua,
594575559 BytesPeringatan Masih banyak pekerjaan sebelum saya selesai bermain golf ini! Saya harus bisa mengambilnya di bawah 500 Bytes, setidaknya. Untuk saat ini, ini solusi pertama yang berhasil, dan saya masih mengerjakannya.
Saya akan memberikan penjelasan lengkap setelah saya selesai.
sumber
Rust,
496495 byteSayangnya saya tidak bisa mengalahkan OP, tetapi untuk jawaban Rust saya cukup puas dengan bytecount.
Input: vektor angka serta jumlah kolom. Misalnya
output
ke baris perintah.
Saya pertama-tama memecahkan setiap baris dan kemudian menyelesaikan kolom yang dihasilkan hanya sekali, tetapi mencetak langkah-langkah untuk semua kolom. Jadi sebenarnya cukup efisien :-P.
Dengan formating:
Sunting: sekarang mengembalikan warna solusi yang menyelamatkan saya titik koma ^^
sumber
Befunge ,
197368696754 Bytes(ya, saya sedang melakukan beberapa kode golf terbalik, semakin banyak byte semakin baik)
Saya berpikir itu bisa menjadi tantangan untuk menulis algoritma ini di Befunge dan itu bisa menyenangkan
Saya ingin ini menjadi program komunitas, jadi jika ada yang ingin mengerjakannya, silakan lakukan.Pada akhirnya, saya membuat semuanya sendirian sejauh ini, jadi saya akan menyelesaikannya sendiri (hampir selesai)
Apa yang sudah dilakukan: kode berbentuk troll
(Ya, itu troll, percayalah)
Pada dasarnya, ini membaca sebuah array dan menghitung langkah yang harus dilakukan untuk menyelesaikan baris, diberi input sebagai
(seluruh array dilewatkan sebagai daftar [row1, row2, row3, ...])
output adalah
baris dan cols keduanya dimulai pada 0.
Sekarang baris diselesaikan, hampir selesai! Hore!
Penjelasan: (akan diperbarui nanti)
Jadi ada 5 bagian utama:
Bagian abu-abu adalah inisialisasi
Berikut ini adalah penjelasan yang lebih dalam tentang modul yang menemukan kotak to untuk digabungkan (yang dikodekan di sini, by the way)
Bagian CALL adalah ketika penunjuk instruksi pergi ke modul lain, untuk menggabungkan ke kotak. Ia kembali ke modul ini melalui entri 'B'
Berikut adalah beberapa kode pseudo: (currentx terkait dengan membaca array) Untuk:
Perhatikan bahwa jika Anda ingin mengujinya, Anda harus meletakkan beberapa trailing space dan trailing baris baru sehingga ada cukup ruang untuk menyimpan array, jika Anda ingin menggunakan interpretasi yang saya tautkan. 22 + jumlah baris dalam input sebagai garis trailing, dan 34 + jumlah kolom sebagai spasi tambahan pada satu baris harus ok.
sumber
\r\n
bukan\n
hanya?)C, 404 byte
Golf kode pertama saya, saya cukup senang dengan hasilnya. Butuh waktu terlalu lama. Ini tidak sepenuhnya standar C, hanya apa pun yang akan dikompilasi di bawah gcc tanpa bendera khusus (dan mengabaikan peringatan). Jadi ada fungsi bersarang di sana. Fungsi
f
mengambil dimensim
dann
sebagai argumen pertama, dan karena argumen ketiga dibutuhkan mengambil (int pointer) ke array ukuranm
×n
(diindeks oleh baris pertama). Argumen lain adalah argumen dummy, Anda tidak perlu meneruskannya, mereka hanya di sana untuk menyimpan byte pada mendeklarasikan variabel. Ini menulis setiap pasangan berubah menjadi STDOUT dalam formatrow1,col1:row1,col1;
, dengan tanda titik koma memisahkan pasangan. Menggunakan pengindeksan berbasis 0.Saya menggunakan algoritma yang sedikit berbeda dari OP untuk memecahkan baris / kolom individu. Bunyinya seperti ini (kodesemu):
The
for(;~b;b--)
mengeksekusi lingkaran tepat dua kali, di kedua pass memecahkan kolom bukannya baris. Ini dilakukan dengan menukarn
danm
, dan mengubah nilai-nilaio
danp
yang digunakan dalam aritmatika pointer untuk mengatasi array.Berikut adalah versi yang tidak dikenali, dengan tes utama, dan mencetak seluruh array setelah setiap gerakan (tekan enter untuk langkah 1 giliran):
sumber