2 Kucing dalam Quine


30

Tantangan

Buat dua program, A dan B, yang keduanya merupakan program kucing dalam bahasa yang sama. Ketika digabungkan, AB (juga dalam bahasa yang sama) harus berupa quine.

Misalnya, anggap hellodan worldkeduanya adalah program kucing dalam bahasa XYZ. Jika helloworldquine dalam bahasa tersebut, maka solusi Anda valid.

Bagi Anda yang tidak terbiasa dengan kucing dan quines, program kucing adalah yang mencetak persis apa yang diberikan kepadanya melalui stdin dan quine adalah program yang mencetak kode sumbernya sendiri.

Penilaian dan Aturan

  • Hitungan byte total dari program AB gabungan adalah skor Anda. Karena ini golf kode, skor terendah akan menang.
  • Celah standar dilarang
  • Input harus diambil dari stdin dan output harus pergi ke stdout.
  • Program kucing tidak perlu mengambil argumen; mereka hanya perlu menyalin stdin ke stdout.
  • Quine harus bekerja ketika program tidak diberi input, tetapi tidak harus bekerja dengan benar (tetapi mungkin) untuk input lainnya.
  • Quine tidak perlu diakhiri, asalkan mencetak persis kode sumbernya sekali, tidak lebih.
  • Quine harus berukuran setidaknya satu byte.
  • A dan B dapat berupa program yang sama.
  • BA tidak perlu menjadi quine atau bahkan program yang valid.

Saya tidak berpikir Anda harus memiliki A dan B bisa menjadi aturan program yang sama
Muhammad Salman

2
@MuhammadSalman Ide awal saya adalah membuat program kucing digandakan untuk berubah menjadi quine. Saya hanya ingin membuka pintu untuk solusi yang lebih mudah karena saya tidak sepenuhnya yakin itu mungkin. Sepertinya saya salah dalam kedua hal, tapi saya baik-baik saja dengan itu.
Beefster

3
Anda mungkin harus menambahkan yang ABtidak boleh kosong, karena banyak bahasa memiliki 0-byte cat yang memungkinkan quine 0-byte.
DJMcMayhem

9
@DJMcMayhem quine 0-byte tidak akan menjadi quine yang valid.
Nissa

4
Apa itu program kucing?
Pedro A

Jawaban:


32

V , 2 + 2 == 4 byte

2i2i

Coba quine!

Coba kucingnya!

A adalah2i

B juga2i

Bagaimana cara kerjanya?

Pertama, beberapa penjelasan tentang cara kerja V. Satu hal penting yang memungkinkan jawaban ini adalah bahwa di V, program kosong adalah program kucing. Ini bukan kasus khusus, ini melekat pada bagaimana V beroperasi. Pada startup, semua input dimuat ke dalam "buffer", setiap perintah memodifikasi buffer di suatu tempat, dan kemudian ketika program selesai, buffer dicetak secara implisit. Ini berarti bahwa setiap string NOP juga merupakan program kucing.

The isarana perintah masuk insert modus , yang berarti setiap karakter menyusul iakan ditambahkan ke dalam buffer. Dengan nomor sebelumnya, teks itu akan digandakan n kali.

Ini berarti bahwa untuk program kucing, tidak ada yang akan ditambahkan ke buffer, dan itu akan dicetak saat dibaca. Dengan kata lain:

        " (Implicitly) Load all input
2       " 2 times,
 i      " Insert the following text into the buffer...
        " (nothing)
        " (Implicitly) Print the buffer

Tetapi untuk quine, ada teks setelah i:

2       " 2 times,
 i      " Insert the following text into the buffer...
  2i    "   "2i"
        " (Implicitly) Print the buffer

Nakal tidak menjawab

V , 0 byte

Cobalah online!

A adalah program kosong.

B juga merupakan program kosong.

: P


21
Setiap bahasa lain: Oy, kami menemui jalan buntu! . V: * memposting standar quine * .
Erik the Outgolfer

13

Ruby, 71 byte

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Dapat dipecah menjadi kucing sebagai berikut:

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

dan

;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Kedua kucing identik kecuali 2 yang memimpin, yang merupakan no-op di ketiga program. Ini <<2adalah herestring, artinya segala sesuatu yang dimulai pada baris berikutnya sampai 2 terminasi pada barisnya sendiri adalah string, yang kita gabungkan dengan sendirinya ( *2) dan menambahkan trailing 2. Pada kucing, herestring terbentuk dengan baik tetapi kosong, jadi ekspresi reguler tidak akan cocok dengan itu dan kami akan jatuh ke $<.readekspresi dan output STDOUT. Namun, setelah kami melakukan concat pada kucing, string tidak akan berhenti sampai baris ketiga, jadi regex cocok dan kami melakukan hubungan pendek dan mengeluarkan quine.


11

Pyth, 29 byte (5 + 24) 27 byte (5 + 22)

pz=T0?TzjN*2]"pz=T0?TzjN*2]     # Quine
pz=T0                           # Cat A
     ?TzjN*2]"pz=T0?TzjN*2]     # Cat B

Itu tadi menyenangkan.
Coba quine di sini.
Coba kucing pertama di sini.
Coba kucing kedua di sini

Penjelasan

Cat A
pz=T0
pz       Print the input.
  =T0    (Irrelevant for cat)

Cat B
?TzjN*2]"pz=T0?TzjN*2]
?Tz                      If T (10) is truthy, output the input.
   jN*2]"pz=T0?TzjN*2]   (Irrelevant for cat)

Quine
pz=T0?TzjN*2]"pz=T0?TzjN*2]
pz                            Print the (empty) input (without a newline).
  =T0                         Set T to 0.
     ?Tz                      If T (0) is truthy, output the input.
             "pz=T0?TzjN*2]   Otherwise, get this string...
          *2]                 ... take two copies...
        jN                    ... and join them with a quote.

11

C # (Visual C # Compiler) , 551 byte

A: 95 byte

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//

Cobalah online!

B: 438 + 18 byte

class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Cobalah online!

A + B: 533 + 18 byte

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Cobalah online!

A dan B menerima input sebagai argumen baris perintah. A + B mengabaikan input apa pun. 18 byte pada B dan A + B ditambahkan untuk /p:StartupObject=Bopsi yang dikirim ke MSBuild. Ini hanya benar-benar diperlukan pada A + B, tetapi sepertinya curang untuk tidak juga memilikinya di B. Dengan cara ini, bendera kompiler untuk A + B adalah bendera kompiler untuk A (tidak ada) ditambah bendera kompiler untuk B.

Penjelasan

Program A sangat mudah. Kelas A berisi variabel statis (tidak terpakai) idiinisialisasi ke 2, dan mencetak argumen pertamanya ketika dijalankan. Pada //akhirnya adalah penting untuk kode A + B, tetapi tidak melakukan apa pun dalam A itu sendiri.

Program B aneh dalam isolasi, tetapi pada dasarnya sama. Itu menciptakan Kelas A yang berisi variabel statis idiinisialisasi ke 0, dan kemudian menjalankan metode Utama Kelas B, yang melakukan hal yang sama dengan Program A karena A.ikurang dari 1, dan kembali sebelum hal-hal aneh. Baris baru tidak diperlukan di sini, tetapi penting untuk A + B.

Ketika digabungkan, //dari Program A mengomentari deklarasi Kelas A dari Program B, tetapi karena baris baru, Kelas B baik-baik saja, yang memungkinkan A.iuntuk merujuk pada 2nilai dari Program A sebagai gantinya. Bendera Kompiler membuat Program dijalankan B. Utama () karena A. Utama () juga ada. Hasilnya adalah bahwa Program A + B tidak menampilkan argumennya, tetapi sebaliknya menuju ke segmen B.Main (), yang pada dasarnya hanyalah standar C # quine .


1
"program kucing ... perlu menyalin stdin ke stdout"
Jakob

9

Haskell , 116 + 20 = 187 175 174 136 byte

Banyak byte yang disimpan sejak Ørjan Johansen menunjukkan kepada saya interact

Kucing 1

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact id

Cobalah online!

Kucing 2

main|1>0=interact id

Cobalah online!

Quine

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact idmain|1>0=interact id

Cobalah online!


Prinsip dasar yang bekerja di sini adalah bahwa ketika kita menambahkan kucing kedua ke kucing pertama kita mengubah nama fungsi yang berinteraksi dengan kita dari amenjadi idmain. Karena interact idkucing, kami ingin idmainsaya fungsi yang mengembalikan quine. Solusi yang jelas akan digunakan const, namun karena kita dapat menganggap inputnya adalah (++)karya kosong juga. Dari sini kami menemukan kode sumber melalui sarana standar cantik, kami memiliki variabel gyang menyandikan sumber dan kami menggunakan pembungkus khusus untuk mencetaknya dalam bentuk string dan bentuk kode. Ada sedikit pengecualian bahwa kita perlu meletakkan encoder kita di depan karena kita sudah harus mengakhirinya interact id. Ini berarti tambahang=tidak dikodekan dan harus ditangani secara manual. Kucing kita berikutnya cukup standar kecuali kita harus membuatnya menjadi kode yang valid ketika ditempelkan ke ujung kucing lain sehingga kita membutuhkan kedua kucing itu sebagai contoh penjaga pola.

Strategi Alternatif, 43 + 105 = 186 148

Kucing 1

g="";main|idmain<-(++g++show g)=interact id

Cobalah online!

Kucing 2

main|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Cobalah online!

Quine

g="";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Cobalah online!


1
Anda dapat mempersingkat itu sedikit dengan mengganti getContents+ putStrdengan interact id. Cobalah online! (Quine tidak lagi berfungsi dengan input non-kosong, yang memungkinkan menggunakan (++ ...)bagian untuk idmain.)
Ørjan Johansen

@ ØrjanJohansen Terima kasih! Saya tidak tahu interact, saya kira itu karena saya jarang melakukan hal-hal IO dengan Haskell. Saya telah mengedit pos.
Wheat Wizard

8

Python 3, 286 byte

Golf Python pertamaku dan quine pertamaku! Tidak terlalu elegan, tetapi berhasil.

Program A (238 byte)

from atexit import*;s="from atexit import*;s=%r;register(lambda:print(end='b'in globals()and s%%s or open(0).read()));b=0\nif's'not in vars():print(end=open(0).read())";register(lambda:print(end='b'in globals()and s%s or open(0).read()));

(tidak ada baris baru)

Program B (48 byte)

b=0
if's'not in vars():print(end=open(0).read())

(tidak ada baris baru)

Cobalah secara Online

Ucapan Terima Kasih

  • -24 byte terima kasih kepada Jo King
  • -82 byte terima kasih kepada Jo King

Anda dapat melakukan end=open...dan menggunakan %rdaripada %stidak harus melakukan baris baru dan kutipan
Jo King

Keren, saya beralih ke %r. Tidak yakin apa yang Anda maksud tentang baris baru.
Jakob

1
Alih-alih %smemformat baris baru, Anda bisa melakukan literal \n. Anda juga dapat menggunakan ;untuk memecah pernyataan alih-alih \n(kecuali ifkebutuhan harus sesuai keinginannya). %dapat lolos dalam string dengan melakukan %%. Satu-satunya argumen yang diperlukan untuk memformat string adalah string itu sendiri, segala sesuatu yang lain dapat dikupas
Jo King

1
Program B (dan teks untuk itu) dapat digunakan locals()untuk menyimpan 2 byte.
Jonathan Allan

6

C ++ (dentang) , 313 + 102 = 415 byte

Program A (berakhir di baris baru):

#include<cstdio>
#define Q(x,y)#x,B=#y;x
int c;auto I="#include<cstdio>",A=Q(int main(){if(c)printf("%s\n#define Q(x,y)#x\",\"#y;x\nint c;auto I=\"%s\",A=Q(%s,)\n#ifdef Q\nint n=++c;\n#else\n%s\n%s\n#endif",I,I,A,I,B);else while((c=getchar())>=0)putchar(c);},int c;int main(){while((c=getchar())>=0)putchar(c);})

Program B (tidak berakhir di baris baru):

#ifdef Q
int n=++c;
#else
#include<cstdio>
int c;int main(){while((c=getchar())>=0)putchar(c);}
#endif

Tidak terlalu licik, dan seperti biasa C ++ tidak terlalu bagus untuk quining. Saya tidak akan terkejut jika ada cara untuk mencukur byte di sana-sini dengan ide yang sama. Tangkapan kecil adalah mengubah perilaku sesuatu setelah itu telah ditetapkan, dan penginisialisasi variabel dinamis dengan efek samping melakukan trik. (Bisakah ini dilakukan di C tanpa ekstensi kompiler?)

Cobalah online: A , B , AB

(Satu-satunya masalah portabilitas yang saya ketahui adalah bahwa program ini mengasumsikan <cstdio>menempatkan nama baik di namespace global dan juga std.)



5

Python 3 , 100 + 37 = 137 byte

Program A:

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#

Cobalah online!

Program B:

print(end=open(0).read())
print(s%s)

Cobalah online!

Jadikan Quine AB

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#print(end=open(0).read())
print(s%s)

Cobalah online!

Hanya berfungsi ketika input kosong, jika tidak maka input akan ditambahkan ke output.


Kutipan ganda harus menjadi satu.
Jonathan Allan

Kecelakaan diizinkan?
Jakob

@ Jakob Pertanyaannya tidak mengatakan bahwa menabrak tidak diperbolehkan, dan biasanya output ke STDERR diabaikan
Jo King

OK cukup adil. Pintasan pintar!
Jakob

4

Attache , 15 + 126 = 141 byte

SEBUAH:

AllInput[]|Echo

Cobalah online!

B:

@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Cobalah online!

A + B:

AllInput[]|Echo@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Cobalah online!

Penjelasan

Setiap program kucing mengkodekan AllInput[]|Echo, yang merupakan program kucing sederhana. B adalah fase quine utama; sendirian, itu adalah fungsi vektor (melalui unary @) yang disebut tanpa input (disebut sebagai |Call). Dengan demikian, kondisional pertama If[_,A,B]dijalankan B, yang sederhana AllInput[]|Echo.

Ketika A + B dieksekusi, unary @menjadi biner @karena Echobergabung dengan lambda:

AllInput[]|Echo@{If[_, ...

Ini berarti lambda dieksekusi sebelumnya Echo. Kembali ke persyaratan, fungsi ini sekarang memiliki semua STDIN sebagai argumen. Jadi, If[_,A,B]jalankan A, yang merupakan kerangka standar quine.


3

Stax , 16 + 12 = 28 byte

Kucing 1:

"yi|d|ca34b4lr"y

Jalankan dan debug itu

"yi|d|ca34b4lr"y Full program, implicit input
"yi|d|ca34b4lr"  Push the string
               y Push raw input
                 Implicit output of top item

Kucing 2:

i|d|ca34b4lr

Jalankan dan debug itu

i|d|ca34b4lr Full program, implicit input
i            Don't parse input (prefix directive)
 |d          Push main stack depth, always zero
   |c        Cancel because top item is falsy, and implicitly print
     a34b4lr Never executed

Quine:

"yi|d|ca34b4lr"yi|d|ca34b4lr

Jalankan dan debug itu

"yi|d|ca34b4lr"yi|d|ca34b4lr Full program
"yi|d|ca34b4lr"              Push the string
               y             Push input
                i            No-op
                 |d          Push main stack depth, i.e. 2
                   |c        Do nothing because top is truthy
                     a       Get the string to the top
                      34     Push 34 (charcode of ")
                        b    Copy both
                         4l  Listify top 4
                           r Reverse
                             Implicit output

3

Kucing 1:

Lua , 41 byte

a=io.read;while a(0)do io.write(a(1))end;

Cobalah online!


Kucing 2:

Lua , 70 byte

if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Cobalah online!


Quine:

Lua , 111 byte

a=io.read;while a(0)do io.write(a(1))end
if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Cobalah online!

io.input(arg[0]) di Cat 2 mengatur file saat ini sebagai input standar, dan sebagai hasilnya, kucing mencetak kode sumber


1
Selamat datang di PPCG
Muhammad Salman

Anda dapat menyimpan satu byte di cat 1 dengan menghapus semi-colon terakhir?
Muhammad Salman

1
Sayangnya, membaca file saat ini adalah celah standar. Tapi tetap bagus coba.
Beefster


0

JavaScript (Node.js) , 199 byte


a=()=>console.log(require('fs').readFileSync(0)+'');a();var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Cobalah online!

Cat A, 57 byte


a=()=>console.log(require('fs').readFileSync(0)+'');a();

Cobalah online!

Cat B, 142 byte

var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.