Tantangan Anda sederhana. Tulis dua program yang tidak berbagi karakter yang menghasilkan satu sama lain.
Contoh
Dua program P dan Q adalah quine yang saling eksklusif jika:
- P output Q
- Q output P
- Tidak ada karakter c yang termasuk P dan Q
- Setiap program P dan Q adalah quine yang tepat
- Ini menghitung quines kosong dan quine yang membaca kode sumbernya sendiri (atau yang lain) tidak valid .
Lebih banyak aturan
- Panjang gabungan terpendek dari semua program ini akan menang. Artinya, ukuran ( P ) + ukuran ( Q ) adalah skor Anda, dan skor terendah menang.
- Kedua program dalam bahasa yang sama
- Setiap program dapat berupa program atau fungsi lengkap, dan tidak harus sama.
- Sebagai contoh, P mungkin merupakan program lengkap dan Q mungkin suatu fungsi.
Verifikasi
Ini Coba online! cuplikan di sini dapat memverifikasi apakah dua program bersifat eksklusif atau tidak. Masukan dimasukkan dalam dua argumen pertama.
code-challenge
quine
Conor O'Brien
sumber
sumber
Jawaban:
> <> , Nilai: 41 + 41 = 82
Sunting: keduanya berisi 3. Tetap
dan
Cobalah online! (tukar baris untuk mendapatkan hasil lainnya) Dengan verifikasi kali ini!
><>
adalah bahasa yang sangat sulit untuk digunakan di sini, karena hanya ada satu cara untuk menghasilkan karakter, perintaho
. Untungnya, kita dapat menggunakan perintah p ut untuk menempatkano
kode sumber dalam eksekusi, seperti dalam Pemrograman saya di jawaban Dunia Pristine .Yang ini mengambil banyak trial and error. Saya mulai dengan dua program yang saling eksklusif:
dan
Masing-masing mengubah dirinya dan datanya dengan N, yang pertama mengurangkan dan yang kedua menambahkan. Ini kemudian menampilkan ini secara terbalik. Intinya adalah bahwa data setelah masing-masing program adalah program lain secara terbalik, digeser oleh N. (
X
adalah nomor sel di mana program perlu meletakkano
dan Y adalah sel di mana penunjuk loop kembali ke.?
Adalah tempat yango
diletakkan) .Keduanya mengikuti struktur yang sama, diwakili dengan cara yang berbeda. Mereka menjalankan string literal di seluruh kode, menambahkannya ke stack. Mereka menciptakan kembali perintah string literal yang mereka gunakan dan meletakkannya di bagian bawah tumpukan. Mereka berputar di atas tumpukan, menambahkan / mengurangi N ke setiap karakter dan mencetaknya.
Program pertama menggunakan
'
string literal, dan sederhanad3*}
untuk membuat nilai 39 dan mendorongnya ke bagian bawah tumpukan. Yang kedua menggunakan"
string literal dengan fungsi yang sama. Itur
membalik tumpukan,g
ets karakter di sel 0,0 dan membalikkan tumpukan lagi. Kemudiang
ets nilai pada sel 4.0 (g
) dan menambahkan 8 untuk mendapatkano
dan menempatkannya di X.Kedua program menggunakan metode pengulangan yang berbeda. Program pertama menggunakan perintah lewati (
!
) untuk menjalankan hanya setengah instruksi saat ke kiri, membalikkan arah dan menjalankan setengah lainnya. Yang kedua menggunakan perintah lompat (.
) untuk melompat mundur ke awal loop di sel Y. Keduanya berjalan sampai tidak ada lagi item di stack dan kesalahan program.Saya mengalami sejumlah masalah dengan sebagian besar nilai N yang lebih rendah, karena menggeser satu karakter akan mengubahnya menjadi karakter lain yang penting untuk program itu (dan karena itu tidak dapat digunakan sebagai data untuk program lain) atau dua karakter dari dua program akan berubah menjadi karakter yang sama. Sebagai contoh:
+
+1 =,
=-
-1.
+2 =0
*
=-
-3g
+4 =k
=o
-4dll.
Akhirnya saya sampai ke 10 (
a
), di mana saya bisa menghindari masalah ini. Mungkin ada versi yang lebih pendek di mana shift dibalik, dan program pertama menambahkan N sementara yang kedua menguranginya. Ini mungkin lebih buruk, karena program pertama umumnya di ujung bawah skala ASCII, jadi mengurangi lebih baik untuk menghindari konflik.sumber
Keempat (64-bit little-endian gforth) , 428 + 637 = 1065 byte
Cobalah online!
Skrip verifikasi
Terima kasih kepada @Nathaniel untuk gagasan menggunakan Forth - dia mengingatkan saya dalam komentar bahwa Forth tidak peka huruf besar-kecil . Kemudian datang perubahan suasana hati - saya telah menemukan alasan mengapa ini tidak akan berhasil, diikuti oleh solusi untuk masalah ini, lagi dan lagi. Semua sambil memutar sepeda pelatihan dalam ruangan saya seperti spinner gelisah oversized dan cacat (Anda hanya perlu mengambil salah satu ujung handle bar dan memiringkannya sedikit).
Sebelum menulis program ini, saya membuat konsep karakter apa yang dapat digunakan oleh program mana. Secara khusus, program kedua hanya dapat menggunakan huruf besar, angka desimal, tab, dan koma. Ini berarti bahwa program pertama semuanya huruf kecil, tetapi saya menggunakan beberapa huruf besar untuk nilai ASCII mereka.
Karena tab sulit digunakan, sebagai gantinya saya akan menggunakan spasi dalam penjelasan.
Program pertama berbentuk
s" code"code
-s"
mulai string literal, yang kemudian diproses oleh salinan kedua kode - kerangka kerja standar quine. Namun, alih-alih mengeluarkan kode sumbernya sendiri, itu akan membuat program lain, yang terlihat seperti ini:HERE
64-bit-number-literal ,
length-of-the-string
115 EMIT 34 EMIT 9 EMIT 2DUP TYPE 34 EMIT TYPE
Ini menggunakan ruang data Forth.
HERE
mengembalikan pointer ke ujung area ruang data yang saat ini dialokasikan, dan,
menambahkan sel diisi dengan angka padanya. Oleh karena itu, tiga poin pertama dapat dilihat seperti string literal yang dibuat menggunakans"
. Untuk menyelesaikan program kedua:EMIT
mengeluarkan karakter yang diberi nilai ASCII, jadi:115 EMIT
mencetak huruf kecils
34 EMIT
mencetak karakter kutipan"
9 EMIT
mencetak tab2DUP
menduplikasi dua elemen teratas pada stack( a b -- a b a b )
, ini dia pointer ke dan panjang stringTYPE
mencetak string untuk menampilkan salinan kode yang pertama34 EMIT
mencetak kutipan penutup"
, dan akhirnyaTYPE
menampilkan salinan kedua kodeMari kita lihat bagaimana program pertama bekerja. Dalam banyak kasus, angka harus dihindari, yang dilakukan menggunakan
'x
ekstensi sintaksis gforth untuk literal karakter, dan kadang-kadang mengurangi nilai ruang ASCII, yang dapat diperoleh dengan menggunakanbl
:Untuk menyelesaikan ini, saya ingin mengatakan bahwa saya mencoba menggunakan
EVALUATE
, tetapi program kedua menjadi lebih besar dari yang disajikan di atas. Bagaimanapun, ini dia:Jika Anda berhasil mengurangi jumlah ini untuk mengalahkan
s" ..."...
pendekatan saya , silakan dan posting sebagai jawaban Anda sendiri.sumber
Perl,
(311 + 630 = 941 bytes)190 + 198 = 388 bytesKedua program mencetak ke output standar.
Program perl pertama berisi sebagian besar karakter ASCII yang dapat dicetak dan baris baru, dan berakhir tepat satu baris baru, tetapi dua huruf ÿ mewakili byte non-ASCII \ xFF:
Yang kedua sebagian besar berisi byte non-ASCII, termasuk beberapa karakter kontrol tinggi yang digantikan oleh bintang di pos ini, dan tidak ada baris baru sama sekali:
Hexdump dari program pertama
xxd
adalah:Dan hexdump dari program kedua adalah:
Dalam program kedua, string yang dikutip (panjang 189 byte, dibatasi oleh tildes) adalah keseluruhan program pertama kecuali baris akhir final, hanya dikodekan dengan bitwise melengkapi setiap byte. Program kedua hanya menerjemahkan string dengan melengkapi masing-masing byte, yang dilakukan oleh
~
operator dalam perl. Program mencetak string yang didekodekan diikuti oleh baris baru (say
metode menambahkan baris baru).Dalam konstruksi ini, decoder dari program kedua hanya menggunakan enam karakter ASCII yang berbeda, sehingga program pertama bisa dibilang sewenang-wenang, asalkan hanya berisi karakter ASCII dan tidak termasuk keenam karakter tersebut. Tidak sulit untuk menulis program perl tanpa menggunakan lima karakter tersebut. Logika quine aktual dengan demikian dalam program pertama.
Dalam program pertama, logika quine menggunakan kamus panjang 11 kata
@f
, dan mengumpulkan output dari kata-kata itu. Kata-kata pertama mengulangi sebagian besar kode sumber dari program pertama. Kata-kata lainnya adalah karakter tunggal spesifik. Sebagai contoh, kata 5 adalah tilde, yang merupakan pembatas untuk dua string literal dalam program kedua. Daftar angka di antara tanda kurung adalah resep untuk mencetak kata-kata dalam urutan apa. Ini adalah metode konstruksi umum yang cukup biasa untuk quines, satu-satunya twist dalam hal ini adalah bahwa kata-kata kamus pertama dicetak dengan byte-bitnya yang dilengkapi bitwise.sumber
Haskell , 306 + 624 = 930 byte
Program 1: Fungsi anonim mengambil argumen dummy dan mengembalikan string.
Cobalah online!
Program 2:
q[[40,...]]
pada akhirnya adalah fungsi anonim mengambil argumen dummy dan mengembalikan string.Cobalah online!
Set karakter 1 (termasuk spasi):
Kumpulan karakter 2 (termasuk baris baru):
Karena hanya set 1 berisi karakter non-ASCII, byte UTF-8 mereka juga terpisah.
Bagaimana itu bekerja
Program 1 umumnya ditulis dengan ekspresi lambda, spasi dan tanda kurung, penggunaan bebas fungsi alfanumerik bawaan, dan dengan data quine sebagai string literal pada akhirnya.
a
ataub
, yang membentuk urutan pelarian yang valid yang melakukan perjalanan pulang pergishow
.a
,b
danc
merupakan satu-satunya huruf kecil yang kode ASCIInya kurang dari 100, menghemat satu digit dalam pengkodean numerik yang digunakan oleh program 2.Program 2 umumnya ditulis dengan persamaan fungsi tingkat atas (kecuali untuk yang anonim akhir), karakter literal dan angka desimal, sintaksis daftar / rentang dan operator, dan dengan data quine sebagai daftar daftar
Int
s pada akhirnya.Panduan, program 1
b
danc
adalah nilai-nilai string literal untuk program 2 dan 1, masing-masing, diberikan sebagai argumen akhir untuk ekspresi lambda.()
adalah argumen dummy semata-mata untuk memenuhi aturan PPCG bahwa program harus mendefinisikan suatu fungsi.foldr(\a->map pred)b(show()>>c)
mendekode stringb
ke kode inti program 2 dengan menerapkannyamap pred
beberapa kali sama dengan panjangshow()>>c == c++c
, atau182
.tail(show c)
mengkonversi stringc
ke kode inti program 1, dengan kutipan ganda akhir ditambahkan.:pure b
menggabungkan ini dalam daftar dengan stringb
.map(map fromEnum)$
mengkonversi string ke daftar poin kode.`mappend`show(...)
membuat serial daftar yang dihasilkan dari daftar dan akhirnya menambahkannya ke kode inti program 2.Panduan, program 2
z~z=[[['@','0'..]!!4..]!!z]
adalah fungsi yang mengubah kode kembali ke karakter (diperlukan untuk menulis karena tidak semua karaktertoEnum
tersedia).z
. Penanda kemalasan~
tidak memiliki efek pada posisi ini tetapi menghindari karakter spasi.['@','0'..]
adalah rentang daftar loncatan mundur mulai dari kode ASCII 64, kemudian melompat 16 ke bawah setiap langkah.!!4
ini memberi\NUL
karakter.[ ..]
rentang memberikan daftar semua karakter, yang!!z
diindeks.z
menggunakan daftar=<<
alih-alih yang tidak tersediamap
dan<$>
.q[x,q]_=z=<<x++q++[34,34]++x
adalah fungsi membangun program 1 dari daftar data quine.x
adalah data untuk inti dari program 1 (termasuk penawaran ganda akhir) dan bagian dalamq
adalah data yang dikaburkan untuk inti dari program 2._
adalah argumen dummy lain semata-mata untuk membuat fungsi anonim akhir menjadi fungsi alih-alih hanya string.x++q++[34,34]++x
menyatukan potongan-potongan, termasuk dua tanda kutip ganda dengan kode ASCII 34.z=<<
membangun program 1 dengan memetakanz
rangkaian untuk mengkonversi dari titik kode ke karakter.q[[40,...]]
adalah fungsi anonim yang dikombinasikanq
dengan data quine.sumber
Jelly ,
128 90 87 86 85 7916 + 32 = 48 byteCobalah online!
Cobalah online!
Program pertama melakukan hal berikut:
Ini meninggalkan string
79,7806,8318,7885,7769,338,115
danỌṘ
sebagai dua argumen rantai dan mereka secara implisit digabungkan dan dicetak pada akhirnya.Program kedua menghitung
chr
(Ọ
) dari daftar angka yang kembaliOṾ⁾ọṙŒs
.Ṙ
mencetak“OṾ⁾ọṙŒs”
(dengan tanda kutip) dan mengembalikan input, meninggalkan“OṾ⁾ọṙŒs”OṾ⁾ọṙŒs
sebagai output penuh.sumber
Gol> <> ,
23 + 23 = 4622 + 22 = 4420 + 20 = 40 byteCobalah online!
Cobalah online!
Verifikasi online!
Bagaimana mereka bekerja
Diadaptasi dari jawaban Jo King> <> . Memiliki lebih banyak perintah alternatif untuk keluaran dan pengulangan, tidak perlu
g
ataup
, dan dua badan utama menjadi jauh lebih pendek.Perbedaan utama lainnya adalah saya membuat kutipan lawan langsung di atas tumpukan. Dengan cara ini, sedikit lebih mudah untuk mempertahankan yang lain
quote + my code + opponent code(reversed and shifted)
.sumber