Kesalahan (atau peringatan) quine yang juga merupakan quine biasa [ditutup]

9

(Terinspirasi oleh komentar ini pada pertanyaan lama.)

Latar Belakang

Sebuah Quine kesalahan (juga dikenal sebagai "Quine Kimian") adalah sebuah program yang, ketika dikompilasi atau menjalankan, menyebabkan compiler / interpreter / runtime untuk mencetak pesan kesalahan yang memiliki teks identik dengan program itu sendiri, dan tidak ada lagi. Untuk keperluan tantangan ini, kami mendefinisikan "kesalahan" secara luas, untuk memasukkan peringatan juga.

Tugas

Dalam tantangan ini, kami sedang mencari yang juga merupakan quine kesalahan. Ketika dijalankan, program harus mencetak kode sumbernya sendiri secara normal (mis. Bukan sebagai pesan kesalahan / peringatan); ini harus quine yang tepat (yaitu beberapa bagian dari program harus menyandikan bagian yang berbeda dari output). Selain itu, mengkompilasi dan menjalankan program juga harus menyebabkan kode sumber program - dan tidak ada yang lain - yang akan dicetak sebagai pesan kesalahan atau peringatan oleh implementasi. (Perhatikan bahwa ini berarti Anda tidak akan dapat menggunakan kesalahan waktu kompilasi, dalam bahasa yang mencegah program untuk mengeksekusi secara normal.) Jadi dengan kata lain, kode sumber program akan dicetak dua kali, sekali melalui setiap metode.

Klarifikasi

  • Dalam kebanyakan kasus, akan jelas apa yang merupakan dan bukan pesan kesalahan / peringatan; kami tidak membedakan antara keduanya di sini. Dalam kasus yang ambigu, tentukan pesan kesalahan / peringatan sebagai teks apa pun yang dihasilkan oleh implementasi: 1. sebagai konsekuensi dari sesuatu selain mengeksekusi perintah (atau apa pun yang setara terdekat dalam bahasa); atau 2. itu bukan bagian dari input ke perintah yang menghasilkannya sebagai output.
  • Bagian kesalahan / peringatan dari quine tidak perlu menjadi quine yang tepat (meskipun dalam kebanyakan kasus itu adalah kebetulan, karena sebagian besar pesan kesalahan dan peringatan mengandung sejumlah besar teks tetap).
  • Ini dapat diterima untuk program untuk menghasilkan beberapa kesalahan / peringatan, yang membentuk sumber program ketika disatukan. Tidak dapat menerima kesalahan / peringatan keluaran yang tidak muncul di sumber.
  • Tidak seperti dalam banyak tantangan, saklar yang diberikan kepada kompiler, dan nama file program, cenderung sangat relevan dalam tantangan ini. Mengingat bahwa tantangannya tidak mungkin terjadi sebaliknya, saya bersedia menjadi fleksibel di sini, walaupun jika Anda menjalankan implementasinya dengan cara yang tidak biasa, ingat bahwa aturan PPCG mengenakan penalti byte untuk melakukannya (sama dengan jumlah karakter tambahan yang Anda perlu menambahkan pada baris perintah melalui cara "normal" terpendek untuk menjalankan program), dan dengan demikian Anda harus menentukan ukuran penalti dalam posting Anda. (Misalnya, jika penerjemah yang Anda gunakan membaca program dari file, dan tidak memiliki batasan khusus pada nama file, cara normal terpendek untuk menjalankan program adalah dari file dengan nama file 1 karakter; dengan demikian,
  • Versi kompiler / juru bahasa yang Anda gunakan mungkin relevan, jadi sebagai bagian dari kiriman Anda, harap sebutkan kompiler atau juru bahasa tertentu tempat program Anda bekerja, dan versi mana yang diperlukan. (Misalnya, pengiriman C mungkin menyatakan "C (gcc 6.2.0)" di header.)
  • Perhatikan bahwa tugas ini mungkin tidak dimungkinkan dalam semua bahasa. Dalam bahasa di mana itu, metode termudah kemungkinan akan menemukan pesan kesalahan atau peringatan yang memungkinkan untuk menyesuaikan beberapa bagian teks (melalui mengubah nama sesuatu yang dikutip dalam pesan; nama file adalah pilihan umum di sini, tetapi bukan satu-satunya). Saya akan sangat terkesan (dan terkejut) jika seseorang menemukan cara untuk melakukan ini hanya menggunakan pesan kesalahan dan peringatan yang teksnya sudah diperbaiki.

Kondisi kemenangan

Ini adalah tantangan , jadi entri dianggap lebih baik jika memiliki jumlah byte yang lebih kecil. Dengan demikian, begitu program Anda berfungsi, Anda ingin mengoptimalkannya untuk menurunkan jumlah byte sejauh mungkin. (Namun, jangan berkecil hati jika sudah ada entri yang lebih pendek, terutama jika itu dalam bahasa yang berbeda; yang benar-benar kita cari di sini adalah untuk mempersingkat algoritma atau ide tertentu di balik program sebanyak mungkin, tetapi melihat banyak solusi dalam bahasa yang berbeda atau yang mengandalkan prinsip yang berbeda selalu bermanfaat.)

Komunitas
sumber
2
Seperti yang saya katakan dalam obrolan, saya pikir poin pertama tidak jelas. Dalam kebanyakan kasus, akan menjadi jelas apakah pesan kesalahan / peringatan hanya dan berfungsi sebagai titik awal untuk diskusi dan lawyering bahasa.
Dennis
@ Dennis: Saya setuju secara prinsip bahwa situasinya tidak hebat, tetapi di sisi lain tidak bisa memikirkan cara konkret untuk memperbaikinya; menghapus pengecualian untuk hal-hal yang jelas pesan kesalahan cenderung menyebabkan beberapa situasi yang sangat tidak disengaja dalam beberapa bahasa, yang mungkin menyebabkan lebih banyak kerusakan daripada menyembuhkannya; jika Anda pikir Anda dapat meningkatkan pertanyaan, saya tidak keberatan untuk itu diedit (dan saya tidak benar-benar berpikir pertanyaan pada PPCG harus memiliki "kepemilikan", meskipun itu masalah yang berbeda)
Karena itu, saya pikir pertanyaannya tidak jelas dan tidak memiliki kriteria validitas obyektif. Saya setuju bahwa perubahan yang saya usulkan dapat memperburuk keadaan. Salah satu tindakan yang mungkin dilakukan adalah menunda tantangan dan memposting ulang di kotak pasir.
Dennis
1
Saya telah menunda tantangan untuk saat ini. Saya harap Anda mempertimbangkan kembali pengeposan ulang di kotak pasir. Itu ide yang sangat menarik, dan akan memalukan untuk membiarkannya sia-sia.
Dennis
1
Posting kotak pasir ada di sini . (Saya sedang mempertimbangkan untuk mengeditnya ke dalam pertanyaan, tetapi itu akan menempatkan pos ke antrean buka kembali, yang akan sangat kontraproduktif karena akan membuat lebih sulit untuk membuka kembali jika dan ketika masalah telah diselesaikan.)

Jawaban:

9

JavaScript (Firefox 50), 153 byte

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

Penjelasan

Gagasannya di sini adalah memulai dengan quine JS yang paling mudah dimodifikasi yang saya temukan:

".replace(/.+/,x=>alert(uneval(x)+x))".replace(/.+/,x=>alert(uneval(x)+x))

Kata throwkunci adalah cara sederhana untuk membuatnya melemparkan kode sendiri juga:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

Namun, ada sedikit masalah: Firefox menambahkan pesan yang dilemparkan Error:. Untungnya, Error: mycodeini sebenarnya JavaScript yang valid! (Untuk mempelajari lebih lanjut tentang ini, kunjungi MDN .)

Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

Ups, ini mengingatkan hal yang salah:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: 

Karena tanda kutip tidak lagi di awal kode, uneval(x)+xtidak akan memberi kami hasil yang benar. Cara terbaik untuk memperbaikinya adalah dengan menambahkan placeholder sebagai ganti string bersarang:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})

Uh-oh, sekarang ada tambahan Error:di pesan kesalahan. Mari kita perbaiki dengan mengiris string:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

Dan akhirnya, baik output dan pesan kesalahan identik dengan kode! Saya akan menambahkan Cuplikan Stack, tetapi sepertinya tidak berfungsi dalam cuplikan di browser apa pun.

Produksi ETH
sumber
5

Python 2, 217 80 51 byte

Diperlukan linefeed tambahan.

s='s=%r;print s%%s;exit(s%%s)';print s%s;exit(s%s)

Cobalah online

Saya mulai dengan quine sederhana:

s='s=%r;print s%%s';print s%s

Kemudian saya menambahkan raisedi akhir untuk melempar IOError.

s='s=%r;print s%%s;raise IOError(s%%s)';print s%s;raise IOError(s%s)

Sayangnya, traceback menyebabkan masalah (saya tidak bisa membuatnya benar-benar hilang), dan nama pengecualian selalu dicetak di depan seperti IOError: <code here>, bahkan jika saya menghapus traceback.

Kemudian saya menemukan jawaban SO yang bermanfaat ini dan memodifikasinya untuk tujuan saya.

Kemudian saya menemukan bahwa saya dapat melewatkan membuat kelas saya sendiri dan hanya dapat menggunakan sys.exit, membuat kode saya jauh lebih pendek.

mbomb007
sumber
1
Saya tidak berpikir ini sesuai dengan definisi kesalahan dalam spec tantangan karena itu bukan sebagai konsekuensi dari sesuatu selain mengeksekusi perintah juga bukan bagian dari input ke perintah yang menghasilkannya sebagai output . Yang mengatakan, polos exitberfungsi dengan baik di sini. Tidak perlu sys.
Dennis