Ini terinspirasi oleh Mencetak Negatif Kode Anda dan Golf bersama .
Pertimbangkan segi empat karakter, yang memenuhi batasan berikut:
- Hanya terdiri dari karakter ASCII yang dapat dicetak
- Dimensi keduanya lebih besar dari 1
- Setiap baris dan setiap kolom mengandung setidaknya satu spasi.
- Setiap baris dan setiap kolom mengandung setidaknya satu karakter non-spasi.
Misalnya, berikut ini adalah persegi panjang 6x4 yang valid:
%n 2e
1 g 3
&* __
3
Sebuah negatif untuk persegi panjang ini didefinisikan menjadi persegi panjang dengan ukuran yang sama, dengan semua ruang diganti dengan karakter non-ruang, dan semua karakter non-ruang diganti dengan spasi. Negatif dari persegi panjang di atas adalah:
f ^
33 >
9 $
^ }|Q'
Karakter ASCII yang dapat dicetak tanpa spasi dapat digunakan untuk mengganti spasi.
Tugas
Tugas Anda adalah menulis program dengan kode sumber persegi panjang, yang menampilkan negatif yang valid untuk dirinya sendiri. Output negatif juga harus merupakan program yang valid, dalam bahasa yang sama dengan yang asli, dan itu harus menampilkan sumber yang asli.
Tidak ada spasi spasi tambahan dapat ditambahkan atau dihapus, kecuali untuk baris tambahan tunggal di akhir dari salah satu output, yang merupakan opsional.
Tidak ada program yang diizinkan membaca kode sumber dari keduanya; lingkungan REPL juga tidak dapat diasumsikan.
Mencetak gol
Skor Anda adalah produk dari dimensi kode Anda (yaitu jika kode sumber Anda dalam persegi panjang 12 dengan 25, skor Anda adalah 12 * 15 = 180). Selain itu, untuk setiap karakter yang digunakan dalam komentar, skor Anda meningkat 2 (Jika Anda menggunakan /* .. */
satu kali dalam kode Anda, dan kode Anda dalam persegi panjang 10 kali 10, skor Anda akan menjadi 10 * 10 + 8 * 2 = 116).
Skor terendah menang.
Jika ada dasi, pengajuan dengan jumlah ruang paling sedikit dalam program (baik yang asli atau negatif, yang memiliki ruang lebih sedikit) menang.
Jika masih ada seri, jawaban sebelumnya akan menang.
Ada bonus -52% , jika menggabungkan yang asli dan negatif bersama-sama menghasilkan quine normal. Sebagai contoh:
Original Negative Combined
A A B B BABA
A A B B ABAB
sumber
Jawaban:
CJam, (
51 49 47 46 4542 x 2) * 48% = 40,32Menjalankan kode di atas memberikan output ini:
menjalankan yang, mencetak kembali sumber aslinya.
Sumber dan output hanya bertukar baris.
Sekarang tiba keajaiban.
Tumpang tindih sumber dan hasil keluaran ke dalam kode berikut:
yang merupakan quine sempurna!
Cobalah secara online di sini
Bagaimana itu bekerja
Semua logika pencetakan berada di baris pertama itu sendiri yang menangani ketiga kasus yang dijelaskan kemudian.
Array pada baris terakhir di atas adalah array yang memiliki blok kode yang sesuai dengan ketiga case.
Kasus 1
Dalam hal ini, panjang tumpukan yang tersisa adalah 0 karena ketika blok dieksekusi, ia hanya memiliki salinan blok itu sendiri, yang awalnya muncul pada langkah ketiga di atas. Jadi kami mengambil indeks
0
dari array terakhir dan menjalankannya:Dalam hal ini, baris kedua adalah no-op sejauh mencetak output yang bersangkutan.
Kasus 2
Dalam kasus ini, tumpukan sudah berisi string kosong, jadi ketika blok kode yang disalin dieksekusi, ia memiliki 2 elemen - string kosong dan blok kode itu sendiri. Jadi kami mengambil indeks
1
dari array terakhir dan menjalankannya:Kasus 3
Dalam hal ini, tumpukan memiliki 6 elemen. Jadi setelah memunculkan blok kode terakhir, panjang array tersisa adalah 5. Kami mengeluarkan indeks
5
dari array dan menjalankannya. (Perhatikan bahwa dalam array3
elemen, indeks5
adalah indeks5%3 = 2
)sumber
Python, 97x2 + 2 = 196
Bukan solusi yang bagus untuk memulai, tetapi setidaknya itu berhasil (saya pikir).
Keluaran:
sumber
CJam, (
5856544846 x 2) * 48% = 44,16yang mencetak
Karakter non-spasi di setiap baris tetap sama di antara kedua quine yang sama.
Tetapi sekarang bagian yang sangat manis:
adalah quine! :)
Uji di sini.
Bagaimana itu bekerja
Saya sarankan Anda membaca penjelasan pada kiriman saya yang lain terlebih dahulu, karena menjelaskan dasar-dasar quining di CJam secara umum.
Yang ini agak rumit. Untuk quine timbal balik, seperti dalam kasus lain, saya memodifikasi representasi string dari blok dengan menambahkan spasi sebelum atau setelah setiap baris, dan menukar 0 dengan 2, sehingga program yang dihasilkan menempatkan spasi di ujung yang berlawanan.
Perhatikan bahwa spasi sama sekali tidak memengaruhi quesi bersama. Yang pertama, mereka berada di blok, yang tidak benar-benar digunakan, dan yang kedua mereka berada di seluruh kode.
Untuk mendapatkan quine reguler ketika menggabungkan keduanya, kita perlu menemukan cara untuk menghindari melakukan semua modifikasi itu. Perhatikan bahwa struktur spasi dan kode berarti bahwa dengan menggabungkan keduanya, kami memasukkan keseluruhan satu quine ke yang lainnya. Jadi, jika kita menempatkan seluruh kode modifikasi dalam satu blok, kita dapat menjalankan blok itu tergantung pada isi sebenarnya.
Jadi sekarang saya punya blok ini ... untuk quines mutual, hanya berisi kode yang sebenarnya ingin saya jalankan. Untuk gabungan quine, ini juga berisi seluruh quine lagi, dalam posisi acak, yang tidak masuk akal ... tetapi karena ini adalah sebuah blok, itu tidak berjalan secara otomatis. Jadi kita dapat menentukan apakah akan memodifikasi string berdasarkan pada isi blok itu. Itu untuk apa
_`'"#)!
. Ini menduplikasi blok, mengonversinya menjadi string, mencari karakter"
(yang, dalam quines mutual, hanya muncul di luar blok) - pencarian kembali-1
jika karakter tidak ditemukan dan bilangan bulat positif sebaliknya -, menambah hasilnya dan meniadakannya secara logis. Jadi jika"
ditemukan ini menghasilkan,0
jika tidak maka akan menghasilkan1
. Sekarang kita lakukan saja*
, yang mengeksekusi blok sekali, jika hasilnya 1 dan tidak sama sekali sebaliknya.Akhirnya, ini adalah cara kerja kode modifikasi:
Mengklaim Bounty, (12 x 10) * 48% = 57,6
Ternyata kode ini dapat dibagi lebih banyak baris dengan sangat mudah dengan beberapa modifikasi. Kami menambahkan 2 karakter, untuk mendapatkan 48 berturut-turut, yang kemudian dapat dengan mudah kita bagi dengan 8, sehingga kita memiliki 8 baris dengan 6 karakter kode dan 6 spasi. Untuk melakukan itu kita juga perlu mengubah beberapa angka, dan mengatur ulang satu atau dua operator, sehingga tidak terpecah di kedua saluran. Itu memberi kita versi yang berfungsi dengan ukuran 12 x 8 ... satu dari persyaratan. Jadi kami hanya menambahkan dua baris yang tidak melakukan apa-apa (tekan 1, pop 1, push 1, pop 1), jadi dapatkan 12 x 10 :
Seperti yang sebelumnya ini menghasilkan
(Catatan: tidak perlu untuk tetap berganti-ganti kiri dan kanan pada garis tengah, hanya posisi baris pertama dan terakhir yang penting. Kiri dan kanan dapat dipilih secara sewenang-wenang untuk semua jalur lainnya.)
Dan melalui kebetulan murni, quine lengkap juga masih berfungsi:
(Saya katakan kebetulan, karena bagian yang mengurus tidak mengeksekusi kode batin sekarang anehnya diselingi dengan quine yang lain, tetapi masih terjadi dengan baik.)
Yang sedang berkata, saya bisa saja menambahkan 44 baris
1;
ke kiriman asli saya untuk memenuhi persyaratan karunia, tetapi12 x 10
terlihat jauh lebih rapi. ;)Sunting: Haha, ketika saya mengatakan "kebetulan murni" saya tidak bisa lebih tepat. Saya melihat bagaimana quine terakhir sekarang benar-benar berfungsi, dan ini benar-benar menggelikan. Ada tiga blok bersarang (sebenarnya 4, tetapi yang paling dalam tidak relevan). Satu-satunya bagian penting dari terdalam dari 3 blok itu adalah bahwa ia berisi
"
(dan bukan yang ia lakukan dalam penyerahan asli, tetapi'"
yang digunakan pada akhirnya untuk memeriksa karakter yang sama). Jadi struktur dasar quine adalah:Mari kita membedah itu:
Jadi ini memang melakukan sihir lucu, tetapi karena blok bagian dalam meninggalkan string tunggal di tumpukan,
)!*
kebetulan mengubahnya menjadi string kosong. Satu-satunya syarat adalah bahwa hal-hal di blok dalam setelah+
tidak melakukan hal lain ke stack, jadi mari kita lihat itu:sumber
Y/2
di quine gabungan?CJam,
423733 x 2 = 66yang mencetak
(Garis ditukar, dan
1
berubah menjadi0
.)Uji di sini.
Bagaimana itu bekerja
Pertama, Anda harus memahami quine CJam dasar:
Kawat gigi hanya mendefinisikan blok kode, seperti fungsi, yang tidak segera dieksekusi. Jika blok yang tidak dieksekusi tetap ada di stack, kode sumbernya (termasuk kawat gigi) dicetak.
_
menduplikasi blok, dan~
mengeksekusi salinan kedua. Blok itu sendiri hanya mendorong string yang berisi_~
. Jadi kode ini, meninggalkan tumpukan dalam status berikut:Blok dan string hanya dicetak kembali-ke-belakang di akhir program, yang menjadikan ini quine.
Keindahan ini adalah bahwa kita dapat melakukan apa pun yang kita inginkan di blok, dan itu tetap menjadi quine, karena setiap bagian dari kode secara otomatis akan dicetak dalam isi blok. Kita juga dapat memodifikasi blok, dengan memperoleh representasi string dengan
`
(yang hanya string blok dengan kawat gigi).Sekarang mari kita lihat solusi ini. Perhatikan bahwa salah satu bagian dari quine mutual berisi blok mirip quine dengan
_~
, dan aL
. TheL
mendorong string kosong ke dalam stack, yang tidak memberikan kontribusi output. Jadi inilah yang dilakukan oleh blok:Jadi ini akan melakukan bagian quine, tetapi menukar 1 untuk 0, dan juga akan menambahkan baris lain dengan
L
, di mana kode di atas memiliki spasi. Tangkapannya adalah bahwa urutan kedua garis ditentukan oleh pertukaran di dalam{ }*
. Dan karena bagian terluar dari quine mutual0
di depannya diganti dengan a1
, ia tidak pernah melakukan swap ini, dan karenanya menghasilkan orde asli lagi.sumber
CJam, 27 × 2 = 54
Keluaran:
'A'B>
membandingkan karakter A dan B.' '\n >
mengembalikan 1 karena 32> 10 dan' \n' >
mengembalikan 0 karena kedua spasi sama.sumber
CJam,
3029 x 2 = 58Output:
yang menampilkan sumber aslinya.
Ini didasarkan pada prinsipal yang sama dengan solusi saya yang lain.
Cobalah online di sini
sumber