Tantangan
Dalam tantangan ini, Anda menentukan bahasa sumber S
dan bahasa target T
. Tugas Anda adalah menulis program berikut P
dalam bahasa ini S
. Jika program yang valid Q
dalam bahasa T
diberikan sebagai input P
, itu akan menampilkan program yang valid R
dalam bahasa T
yang tidak memerlukan input dan output Q(R)
, yaitu, program yang Q
diterapkan pada kode sumber R
. Selain itu , Anda harus mempresentasikan dalam jawaban Anda program contoh nontrivial Q
(semakin menarik, semakin baik, meskipun Anda tidak mendapat poin untuk ini), program yang dihasilkan R
, dan output dari R
. Ini kode-golf, jadi kode terpendek untuk P
menang.
Dengan kata lain, ini adalah tantangan tentang menulis "konstruktor quine universal" yang dapat membuat jenis quines umum yang sewenang-wenang.
Klarifikasi
- Sumber dan bahasa target Anda mungkin identik.
- Program
P
harus mengambil satu string sebagai input (dari STDIN atau yang setara), dan output satu string (ke STDOUT atau setara), sebagaimana seharusnya setiap program outputR
. - Program input
Q
juga harus mengubah string menjadi string lain, tetapi bentuknya lebih fleksibel: mereka dapat berupa fungsi string-ke-string, potongan kode yang memodifikasi variabel dengan nama tertentu, potongan yang memodifikasi tumpukan data jika bahasa target Anda memiliki satu, dll. Anda juga dapat membatasi lebih jauh bentukQ
dengan menyatakan bahwa, misalnya, mereka mungkin tidak mengandung komentar apa pun. Namun, Anda harus dapat mengimplementasikan fungsi string-ke-string yang dapat dikomputasi sebagai program inputQ
, dan Anda harus secara eksplisit menyatakan bagaimana mereka berfungsi dan kendala apa lagi yang Anda tempatkan pada mereka. - Program keluaran
R
harus benar-benar quine (digeneralisasi), jadi ia tidak boleh membaca input apa pun (input pengguna, file, dll.) KecualiQ
melakukannya. - Celah standar tidak diijinkan.
Sebuah contoh
Misalkan saya memilih Python sebagai bahasa sumber saya, dan Haskell sebagai bahasa target saya, dan saya selanjutnya mengharuskan program input harus definisi satu-baris dari suatu String -> String
fungsi bernama f
. Jika saya memberikan program string-reversing
f x = reverse x
sebagai input ke program Python saya P
, itu akan menampilkan kode sumber program Haskell lain R
. Program ini mencetak untuk STDOUT kode sumber R
, tetapi dibalik. Jika P
diberikan fungsi identitas
f x = x
sebagai input, program output R
adalah quine.
sumber
Ekspresi Haskell → Ekspresi Haskell, 41 byte
Cobalah online!
Bagaimana itu bekerja
P $ "Q"
=((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"
dibangun"R"
oleh(++")$(++)<*>show$")
: menambahkan string")$(++)<*>show$"
,('(':)
: mengawali karakter'('
, dan(++)<*>show
(=\x->x++show x
): menambahkan versi yang dikutip itu,menghasilkan
"R"
="(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
.R
=(Q)$(++)<*>show$"(Q)$(++)<*>show$"
bekerja oleh"(Q)$(++)<*>show$"
,(++)<*>show
: menambahkan versi yang dikutip itu,Q
untuk itu,menghasilkan
Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
=Q "R"
.(Paren di sekitarnya
Q
diperlukan karenaQ
mungkin mengandung$
semudah sepertiR
itu, dan$
sayangnya asosiatif benar.)Demo
sumber
$
membutuhkan tanda kurung, tetapi juga trailinglet
,do
atau ekspresi lambda.let
/if
/case
/do
jika saya tidak memancarkannya sendiri. Mungkin sebaiknya aku tidak harus melakukannya.Sumber = Target = JavaScript, 66
Asumsi untuk Q:
Q
harus berupa fungsi anonim JavaScript string-to-string.Contoh:
function(s) { return s.split('').reverse().join(''); }
Dalam hal ini,
P(Q)
(atauR
) akan menjadifunction a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()
:, dan dengan menjalankannya, kita akan mendapatkan:)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnuf
yang persis sama denganQ(R)
.function(s) { return s; }
dalam hal ini,
P(Q)
(atauR
) akan menjadi:function a(){console.log(function(s) { return s; }(a+'a()'))}a()
yang merupakan JavaScript Quine . Tidak perlu dikatakan,Q(R)
akan sama, karena Q adalah fungsi Identitas.Beberapa catatan:
STDIN dalam JavaScript secara tradisional
prompt()
, namun, saya membiarkan diri saya menahan diri dari tradisialert()
sebagai STDOUT, untuk membuat proses menjalankan output sebagai program menggunakan copy-paste lebih mudah. (Saya sadar bahwa saya dapat menyimpan hingga 12 karakter saat mengubah kealert()
).Saya juga dapat membuat segalanya jauh lebih pendek di ES6, tetapi saya ingin tetap menggunakan JavaScript Asli untuk saat ini. Saya sedang mempertimbangkan mengirimkan jawaban S = Scala, T = ECMA6 di masa depan, hanya untuk pengalaman.
Saya juga menyadari bahwa JavaScript hampir tidak pernah bisa mengalahkan CJam dalam kode-golf , tetapi saya harus menerima tantangan ini! Itu masam yang menyenangkan.
sumber
Jeli → 7 , 9 byte
Cobalah online!
Q adalah fungsi 7 (yaitu yang tidak melihat di luar elemen stack atas, dan apakah I / O melalui stack), dan diberikan sebagai argumen baris perintah.
Penjelasan
Program 7
Konstruktor quine universal di 7 yang saya gunakan di sini adalah:
Hal pertama yang perlu diperhatikan adalah bahwa leading 7 sama dengan leading whitespace, dan tidak berpengaruh pada program. Satu-satunya alasan ada di sana adalah untuk mematuhi aturan PPCG terhadap quine literal-only (ini dikodekan oleh yang kedua
1
dalam program daripada dirinya sendiri).Sisa dari program ini adalah elemen tumpukan tunggal (memiliki keseimbangan
7
s dan6
s), yang melakukan hal berikut saat dijalankan:Dengan kata lain, elemen tumpukan ini adalah program yang mencetak bagian atas tumpukan, dengan
7
prepended, dalam format output 7 (yang berarti "mencetak secara harfiah, menggunakan pengkodean yang sama dengan kode sumber", dan dengan demikian jelas merupakan pengkodean terbaik untuk quines). Cukup beruntung di sini bahwa kita dapat menggunakan kembali literal7
untuk dua tujuan (format output, dan spasi putih terkemuka). Jelas, dengan memasukkan sesuatu sebelum final3
, kita dapat menampilkan fungsi7
+ input, daripada hanya memproduksi7
dan masukan secara langsung.Bagaimana elemen tumpukan ini mendapatkan kode sumbernya sendiri? Nah, ketika akhir program tercapai, 7
eval
s elemen tumpukan atas secara default. Namun, itu sebenarnya tidak muncul dari tumpukan dalam proses, sehingga elemen tumpukan literal yangeval
dipimpin masih ada. (Dengan kata lain, program ini tidak membaca sumbernya sendiri - sebagaimana dibuktikan oleh fakta bahwa ia tidak dapat melihat7
pada awal program, yang merupakan pemisah elemen tumpukan daripada bagian dari literal - melainkan, itu sebagian besar terdiri dari literal yangeval
dipimpin secara default.)Program Jelly
Ini mungkin salah satu dari program Jelly yang paling mirip Jelly yang pernah saya tulis; itu terdiri dari tiga nilads (
“ṚƓ^ṾṂ’
,³
,3
), yang hanya output dalam urutan karena tidak ada operasi dilakukan pada mereka. The3
cukup jelas, hanya menjadi integer konstan. Ini³
juga sederhana jika Anda tahu Jelly: itu notasi eksplisit Jelly untuk argumen baris perintah pertama (yang mana Jelly biasanya mengambil inputnya). Sisa dari program Jelly mewakili sebagian besar 7 konstruktor quine universal saya: dengan mengeksploitasi fakta bahwa semua perintah dalam 7 dapat direpresentasikan menggunakan digit ASCII, kita dapat menafsirkan717162234430
bukan sebagai serangkaian perintah, atau bahkan sebagai angka oktal (seperti itu secara konseptual), tetapi sebagai angka desimal, yang berarti bahwa kita tidak memerlukan format khusus untuk output. Angka desimal itu menjadi“ṚƓ^ṾṂ’
dalam notasi bilangan bulat terkompresi Jelly.Contoh
Jika kami berikan
24053
sebagai program Q, kami akan mendapatkan hasil sebagai berikut:Cobalah online!
2405
menggabungkan elemen tumpukan atas untuk dirinya sendiri:(Langkah terakhir mungkin terlihat sedikit membingungkan; apa yang terjadi adalah keluar dari elemen stack mengubah setiap perintah di dalamnya dari "jalankan perintah ini" menjadi "tambahkan perintah ini ke atas tumpukan", sehingga setiap perintah menambahkan sendiri ke aslinya elemen tumpukan atas saat dijalankan.)
Dengan demikian, menjalankan program yang dihasilkan R memberi kita dua salinan R:
sumber
CJam → CJam, 13 byte
Cobalah online!
Input
Q
harus berupa potongan kode yang memodifikasi satu-satunya string dalam tumpukan.Q
dibaca dari stdin.Contoh
Memasukkan:
Ini menambahkan ruang antara setiap dua karakter, dan membalikkan string.
Keluaran:
Output dari quine umum:
Penjelasan
Pertama-tama mengevaluasi quine, jadi kita bisa mendapatkan representasi string-nya tanpa tanda kutip ganda yang tidak perlu. Kemudian ganti muatan dengan input.
Bisa jadi di
{`"_~"+ }_~7qt
mana ruang adalah tempat penampung muatan. Tetapi mengubah payload untuk7
menghemat satu byte.sumber
Arang → Perl (5),
2933 byteCobalah online!
Program Perl Q harus mengembalikan potongan yang mengambil input sebagai string ke sisi kanannya dan memberikan output dalam variabel
$_
. (Fungsi Perl sewenang-wenang dapat dikonversi ke formulir ini melalui membungkusnya sebagaisub x {…}; $_=x
. Namun dalam kebanyakan kasus, sintaksis Perl berarti tidak diperlukan pembungkus.)Penjelasan
Perl
Beginilah bentuk konstruktor universal qu quine:
(Dalam kebanyakan kasus Anda ingin golf turun ini
$_=q(say…"\$_=q($_);eval");eval
, tapi saya tidak yakin Anda dapat memasukkan kode Perl sewenang-wenang ke…
sana.)Dengan kata lain, kami memiliki pembungkus luar
$_=q(…);eval
yang memberikan string ke$_
dan kemudian mengevaluasinya. Di dalam bungkus adalah"\$_=q($_);eval"
, yaitu rekonstruksi bungkus bersama dengan isinya melalui menggunakan nilai yang kami simpan$_
, ditambah kode Q yang ditentukan oleh pengguna, ditambahprint
untuk mencetak output. (Sayangnya kami tidak dapat menggunakansay
; itu menambah baris baru, dan itu relevan dalam quines.)Arang
"Titik" dari jawaban ini adalah untuk menghasilkan quines yang digeneralisasi di Perl, jadi setelah saya memiliki strategi bermain golf untuk melakukan itu (yang saya gunakan dalam banyak jawaban lain), sudah waktunya untuk menulis program P, yang pada dasarnya hanya menggantikan string ke dalam templat. Apa yang saya inginkan di sini adalah bahasa yang bagus untuk mencetak string konstan (idealnya mengompresnya sedikit), dan memasukkan input pengguna ke dalamnya.
Setelah mencoba beberapa, saya memilih Charcoal, yang belum pernah saya gunakan sebelumnya (dan yang benar-benar bisa dilakukan dengan beberapa dokumentasi); itu dirancang untuk seni ASCII tetapi mampu menulis string dalam satu dimensi juga. Karakter ASCII dicetak secara harfiah dalam Charcoal, yang berarti bahwa pencetakan string konstan tidak memerlukan boilerplate, dan kita dapat menggunakan
S
perintah untuk menginterpolasi string yang diambil dari input pengguna ke dalam program.Mungkin saja (sedikit) lebih pendek. Konstruktor quine universal quine berisi dua bagian berulang yang cukup panjang. Dengan demikian kita dapat menggunakan
A
perintah untuk menetapkan mereka ke variabel (misalnyaA…α
menetapkan ke variabelα
), dan cukup menginterpolasi variabel ke dalam string yang kita cetak melalui menggunakan nama mereka. Itu menghemat beberapa byte hanya dengan menulis string secara harfiah.Sayangnya, Charcoal juga menambahkan baris baru ke program, tapi itu bukan masalah besar; itu hanya biaya dua byte untuk
\n
menambahkan baris baru ke input Q juga.Contoh
Jika kita memberikan input
$_=reverse
(yang membalikkan string), kita mendapatkan output berikut:Cobalah online!
yang merupakan quine-sama yang mencetak sumbernya mundur, seperti yang diharapkan.
sumber
Jelly → Underload , 15 byte
Cobalah online!
Mengambil fungsi masukan Underload Q sebagai argumen seperti perintah. Q harus mengambil input dari stack dan mendorong output ke stack, tanpa berusaha memeriksa elemen stack yang lebih dalam (karena mereka tidak akan ada).
Penjelasan
Underload
Konstruktor quine universal Underload yang digunakan di sini adalah:
Sebagian besar program adalah satu literal. Kami mengikutinya dengan
:^
, yang menyalinnya, lalu mengevaluasi satu salinan (meninggalkan salinan lainnya di tumpukan).Ketika literal mulai mengevaluasi, kita menjalankan
a
(escape, yang membawanya kembali ke bentuk yang sama dengan programA asli), dan(:^)*
(yang menambahkan:^
), sehingga merekonstruksi kode sumber seluruh program. Kami kemudian dapat menjalankan fungsi Q untuk mengubah ini dengan cara yang sewenang-wenang, dan mencetak hasilnya denganS
.Jelly
Saya tidak dapat menggunakan Charcoal saat ini karena penerjemah Underload yang valid mogok di akhir program jika program berakhir dengan baris baru. (Beberapa penerjemah Underload, seperti yang ada di TIO, tidak menegakkan aturan ini, tapi saya ingin menjadi portabel dengan baik.) Sayangnya, Charcoal secara alami menambahkan garis baru ke outputnya. Sebaliknya, saya menggunakan Jelly, yang hampir sama singkatnya dalam kasus-kasus sederhana seperti ini; program terdiri dari daftar literal dengan dua elemen (
““”
), dan bergabung dengan mereka pada input (j
), sehingga memasukkan input pengguna ke dalam program.Contoh
Menggunakan input
:S^
(cetak salinan, lalu evaluasi yang asli), kami mendapatkan program Underload berikut:Cobalah online!
Ini mencetak dirinya sendiri berkali-kali, dengan cara yang cukup menarik: setelah melakukan perilaku quine normal, ia kemudian berjalan
eval
pada salinan dari apa yang dihasilkannya. Itu menyebabkan seluruh program yang direkonstruksi berjalan lagi, tanpa batas waktu (Underload bersifat ekor-rekursif). Mengutip diri sendiri dan melakukaneval
sebenarnya adalah satu-satunya cara untuk melakukan loop tanpa batas di Underload.sumber
RProgN 2 , 11 byte
Penjelasan Program
Quine Explination
Quine yang diproduksi sederhana, namun menggunakan fungsionalitas fungsi handler yang tidak tertandingi dalam RProgN2 untuk membuat quine pendek dan manis, yang disebut quine "Looping". Ini adalah konsep yang sangat mirip dengan <> <quine.
Tentu saja, karena struktur quine ini, apa pun kecuali no-ops yang benar (Yang tidak dapat dikompilasi) dapat ditempatkan setelah fungsi gabungan, dan
Beberapa quines
{`{.i}{
: Keluaran{}i.{`{
.i
hanya fungsi "terbalik", jadi output program ini sendiri terbalik.{`{.S§.}{
: Keluaran..S`{{{}§
.S
mengubah string menjadi setumpuk karakter,§
mengurutkan tumpukan secara leksografis, lalu.
menyatukannya kembali, mengeluarkannya sendiri.Cobalah online!
sumber