Kode Puzzle Teka-Teki Gila!

12

Puzzle geser yang paling dikenal adalah puzzle lima belas . Ini memiliki 4 dengan 4 kotak, 15 ubin, dan satu ruang kotak kosong. Ubin hanya bisa bergerak ke ruang kosong dan harus selalu sejalan dengan kisi.

Mari kita mendefinisikan puzzle geser umum sebagai W dua dimensi lebar dengan H grid tinggi ( W , H keduanya bilangan bulat positif) yang berisi sejumlah ubin identik yang tidak bertanda (antara 0 dan W × H dari mereka) yang terpasang pada grid, disusun dalam cara apa pun (tanpa tumpang tindih), dengan ruang kotak kosong mengisi seluruh area.

Misalnya jika W dan H adalah 3 dan ubin adalah Tdan ruang kosong adalah Esalah satu dari banyak pengaturan teka-teki berpihak yang mungkin

TTT
TET
EET

Untuk teka-teki ini ada 4 gerakan yang mungkin: dorong semuanya ke atas , dorong semuanya ke bawah , dorong semuanya ke kiri , atau dorong semuanya dengan benar . 'Mendorong' ke suatu arah membuat semua ubin bergerak ke arah itu sejauh mungkin sampai mereka menyentuh ubin lain atau batas grid. Kadang-kadang mendorong tidak akan mengubah tata letak kotak,

Jika kisi contoh didorong dengan benar hasilnya adalah

TTT
ETT
EET

Mendorong ke kiri hasilnya

TTT
TTE
TEE

Menekan hasilnya adalah

EET
TET
TTT

(perhatikan bahwa kedua ujung kiri Tbergerak)

Mendorong tidak mengubah tata letak kotak dalam kasus ini.

Perhatikan bahwa karena ubin tidak dapat dibedakan, teka-teki ini tidak memiliki status 'terpecahkan'. Perhatikan juga bahwa sebuah puzzle dapat dimulai dari tata letak yang tidak mungkin untuk kembali ke sekali dorongan telah dibuat (misalnya satu ubin di tengah kotak 3 oleh 3).

Tantangan

Dengan hanya menggunakan ASCII yang dapat dicetak, tulis dua blok kode persegi panjang, lebar karakter M dan tinggi karakter N (untuk setiap bilangan bulat positif M , N ). Satu blok kode akan mewakili ubin puzzle geser, blok kode lainnya akan mewakili ruang kotak kosong.

Mengatur dua blok kode ini menjadi W by H grid akan membuat puzzle geser yang diwakili oleh kode yang dapat disimpan sebagai file teks dan dijalankan sebagai program normal. Saat dijalankan, program semacam ini harus meminta pengguna melalui stdin untuk angka dari 1 hingga 4; 1 untuk atas, 2 ke bawah, 3 ke kiri, 4 ke kanan . Ketika pengguna mengetikkan jumlah dan klik mereka masuk, program menghitung bagaimana mendorong petak kode sumbernya ke arah itu dan menyimpan tata letak teka-teki baru dalam file (baik file baru atau file yang sama), lalu berakhir.

Proses ini dapat diulang tanpa batas waktu dengan file kode geser puzzle baru yang dihasilkan setelah setiap dorongan.

Contoh

Misalkan blok kode ubin saya terlihat seperti ini

//   my
// tile

dan blok kode ruang kotak kosong saya terlihat seperti ini

//empty
//space

( M = 7, N = 2, ini tentu saja bukan kode aktual)

Setiap susunan puzzle geser yang valid dari dua blok ini harus membuat program dalam bahasa yang saya gunakan yang dapat dijalankan untuk membiarkan pengguna mendorong ke suatu arah.

Representasi kode dari kisi contoh adalah:

//   my//   my//   my
// tile// tile// tile
//   my//empty//   my
// tile//space// tile
//empty//empty//   my
//space//space// tile

Jadi jalankan ini dan tekan 2 (untuk bawah) kemudian Enter akan menulis ini ke file lain (atau file yang sama):

//empty//empty//   my
//space//space// tile
//   my//empty//   my
// tile//space// tile
//   my//   my//   my
// tile// tile// tile

File itu kemudian dapat dijalankan dan didorong dengan cara yang persis sama.

Catatan

  • Setiap representasi kode dari puzzle geser W oleh H harus dapat dijalankan dan dapat mendorong dirinya dengan benar. Ini termasuk semua ukuran kisi dari 1 oleh 1 hingga beberapa maksimum yang masuk akal (2 16 x 2 16 atau lebih).

  • Suatu program dapat membaca kode sumbernya sendiri. Tidak ada batasan berbasis quine. Komentar apa pun juga baik-baik saja.

  • Program harus meminta arah untuk mendorong bahkan jika tidak ada ubin untuk mendorong atau tidak ada ubin yang bisa didorong. Prompt hanyalah tempat untuk mengetik nomor, tidak ada pesan yang diperlukan.

  • Anda dapat menganggap input selalu valid (1, 2, 3, atau 4).

  • Padding blok kode Anda dengan spasi baik-baik saja. Ingat bahwa mereka hanya dapat dicetak ASCII, ini berarti tidak ada tab dan tidak ada baris baru (selain baris baru yang membantu membentuk blok kode).

  • Jika bahasa Anda tidak mendukung stdin, gunakan metode input apa pun yang tampaknya paling dekat.

  • Anda dapat meminta baris baru di akhir file puzzle-kode Anda. (Atau mengharuskan itu tidak ada di sana.)

  • Bagaimana Anda memberi nama file baru tidak penting. f.txtatau fbaik-baik saja.

  • Dua blok kode mungkin tidak sama.

Mencetak gol

Tujuannya adalah untuk melakukan ini dengan ukuran kode terkecil (itulah sebabnya ini ditandai dengan kode-golf). Pengajuan dengan area blok kode terkecil ( M × N ) adalah pemenangnya. Tie-breaker menuju ke jawaban dengan suara terbanyak.

Terkait: Kode yang menjalankan Game of Life dengan sendirinya

Hobi Calvin
sumber
Jadi program perlu bekerja ketika hanya ada ruang kosong dan tidak ada blok ubin (dan sebaliknya)?
grc
@ grc Ya untuk pertanyaan pertama Anda, dan ingat itu masih perlu meminta nilai dorongan bahkan jika benar-benar kosong atau penuh. Tidak, blok tidak bisa identik. Saya kira jika mereka Anda dapat mengklaim memiliki jawaban yang cukup sepele. Jadi saya akan menyebutkan itu.
Calvin Hobi
Bisakah saya menentukan nama file sumber asli?
feersum
@feersum Sukai Anda dapat menganggapnya selalu f.txt? Iya.
Calvin Hobbies
Bukankah kode kunci selalu menjadi 1 baris? Kode kunci multi-baris tampak sangat rumit bagi saya dan bahasa 2D mungkin tidak memiliki dukungan untuk menulis file.
Def

Jawaban:

5

TECO , 153

Blok kosong:

0T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

Blok ubin:

1T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

Program, yang memodifikasi sendiri di tempatnya, harus disimpan dalam file bernama x. Itu dapat dijalankan melalui perintah tecoc mung x.. Titik itu penting; tanpa itu, TECO berusaha menemukan file bernama x.tec. Baris baru yang tertinggal harus ada.

Pembatasan ASCII yang dapat dicetak sedikit menyakitkan untuk yang ini, karena bahasa ini menggunakan banyak karakter yang tidak patut dicetak. Sebagian besar dari mereka dapat digantikan oleh urutan dua byte yang dimulai dengan tanda sisipan, tetapi "Escape" (ASCII 27) adalah satu karakter yang 'tidak terhindarkan', jadi untuk mendapatkannya saya harus memasukkan nilai ASCII ke dalam string dan exec itu. Dengan demikian, 4-byte EBx<Esc>meledak menjadi @^Ux#EBx#27@:^UX##Mx.

Ini bisa sangat dikurangi, terutama dengan memecah program menjadi dua bagian, menyimpannya sebagai string dan berjalan hanya jika keduanya ada.

feersum
sumber