2 con mèo trong một quine


30

Thử thách

Tạo hai chương trình A và B, cả hai chương trình này đều có cùng ngôn ngữ. Khi nối, AB (cũng trong cùng một ngôn ngữ) nên là một quine.

Ví dụ: giả sử helloworldlà cả hai chương trình mèo trong ngôn ngữ XYZ. Nếu helloworldlà một câu hỏi trong ngôn ngữ nói, thì giải pháp của bạn là hợp lệ.

Đối với những người bạn không quen thuộc với mèo và quines, chương trình mèo là chương trình in chính xác những gì đã được trao cho nó thông qua stdin và quine là một chương trình in mã nguồn của chính nó.

Ghi điểm và nội quy

  • Tổng số byte của chương trình AB được nối là điểm của bạn. Vì đây là mã golf, điểm thấp nhất sẽ thắng.
  • Sơ hở tiêu chuẩn bị cấm
  • Đầu vào phải được lấy từ stdin và đầu ra phải đi đến thiết bị xuất chuẩn.
  • Các chương trình mèo không cần phải tranh luận; họ chỉ cần sao chép stdin vào stdout.
  • Các quine sẽ hoạt động khi chương trình không có đầu vào, nhưng không phải hoạt động chính xác (nhưng có thể) cho các đầu vào khác.
  • Quine không cần chấm dứt, miễn là nó in chính xác mã nguồn của nó một lần, không có gì hơn.
  • Các quine cần phải dài ít nhất một byte.
  • A và B có thể là cùng một chương trình.
  • BA không cần phải là một quine hoặc thậm chí là một chương trình hợp lệ.

Tôi không nghĩ bạn nên có A và B có thể là quy tắc chương trình giống nhau
Muhammad Salman

2
@MuhammadSalman Ý tưởng ban đầu của tôi là có một chương trình mèo được nhân đôi để biến thành một con chuột. Tôi chỉ muốn mở cửa cho các giải pháp dễ dàng hơn vì tôi không hoàn toàn chắc chắn điều đó là có thể. Có vẻ như tôi đã sai về cả hai tính, nhưng tôi ổn với điều đó.
Beefster

3
Có lẽ bạn nên thêm nó ABphải không trống, vì rất nhiều ngôn ngữ có con mèo 0 byte cho phép tạo ra một chuỗi 0 byte.
DJMcMayhem

9
@DJMcMayhem một quine 0 byte sẽ không phải là một quine hợp lệ mặc dù.
Nissa

4
Chương trình mèo là gì?
Pedro A

Câu trả lời:


32

V , 2 + 2 == 4 byte

2i2i

Hãy thử quine!

Hãy thử con mèo!

Một2i

B cũng là2i

Làm thế nào nó hoạt động?

Trước hết, một số giải thích về cách V hoạt động. Một điều đáng chú ý làm cho câu trả lời này có thể là trong V, chương trình trống chương trình mèo. Đây không phải là trường hợp đặc biệt, nó vốn dĩ là cách V vận hành. Khi khởi động, tất cả các đầu vào được tải vào một "bộ đệm", mỗi lệnh sẽ sửa đổi bộ đệm trong một ngày nào đó, và sau đó khi chương trình được thực hiện, bộ đệm được in ngầm. Điều này có nghĩa là bất kỳ chuỗi NOP nào cũng là một chương trình mèo.

Các iphương tiện lệnh nhập chèn chế độ , có nghĩa là tất cả các ký tự sau một isẽ được bổ sung vào bộ đệm. Với một số đứng trước nó, văn bản đó sẽ được nhân đôi n lần.

Điều này có nghĩa là đối với chương trình mèo, sẽ không có gì được thêm vào bộ đệm và nó sẽ được in như đã đọc. Nói cách khác:

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

Nhưng đối với quine, có văn bản sau i:

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

Táo bạo không trả lời

V , 0 byte

Hãy thử trực tuyến!

A là chương trình trống.

B cũng là chương trình trống.

: P


21
Mọi ngôn ngữ khác: Oy, chúng ta đã đi vào ngõ cụt! . V: * bài viết chuẩn 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

Có thể chia thành mèo như sau:

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

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

Hai con mèo giống hệt nhau ngoại trừ 2 người dẫn đầu, đây là điều không có trong cả ba chương trình. Đây <<2là một herestring, có nghĩa là tất cả mọi thứ bắt đầu từ dòng tiếp theo cho đến khi chấm dứt 2 trên dòng của chính nó là một chuỗi, chúng ta nối với chính nó ( *2) và nối thêm một dấu 2. Trong các con mèo, herestring được hình thành rõ ràng nhưng trống rỗng, vì vậy biểu thức chính quy sẽ không khớp với biểu thức và chúng ta sẽ chuyển sang $<.readbiểu thức và đầu ra STDOUT. Mặc dù vậy, khi chúng tôi ghép mèo, chuỗi sẽ không kết thúc cho đến dòng thứ ba, do đó regex khớp và chúng tôi đoản mạch và xuất ra 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

Đó là niềm vui.
Thử quine tại đây
Hãy thử con mèo đầu tiên ở đây
Hãy thử con mèo thứ hai ở đây

Giải thích

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 # (Trình biên dịch C # trực quan) , 551 byte

A: 95 byte

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

Hãy thử trực tuyến!

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);}}

Hãy thử trực tuyến!

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);}}

Hãy thử trực tuyến!

A và B lấy đầu vào làm đối số dòng lệnh. A + B bỏ qua mọi đầu vào. 18 byte trên B và A + B được thêm vào cho /p:StartupObject=Btùy chọn được gửi tới MSBuild. Nó chỉ thực sự cần thiết trên A + B, nhưng có vẻ như gian lận khi không có nó trong B. Bằng cách này, các cờ trình biên dịch cho A + B là các cờ biên dịch cho A (none) cộng với các cờ biên dịch cho B.

Giải trình

Chương trình A rất đơn giản. Lớp A chứa một biến tĩnh (không sử dụng) được ikhởi tạo 2và in đối số đầu tiên của nó khi chạy. Các //ở cuối là quan trọng đối với các mã A + B, nhưng không có gì trong Một chính nó.

Chương trình B là lạ trong sự cô lập, nhưng về cơ bản là giống nhau. Nó tạo ra một lớp A chứa một biến tĩnh được ikhởi tạo 0và sau đó chạy phương thức chính của lớp B, giống như Chương trình A vì A.inhỏ hơn 1 và trả về trước bất kỳ nội dung lạ nào. Các dòng mới không cần thiết ở đây, nhưng rất quan trọng đối với A + B.

Khi được kết hợp, //từ Chương trình A nhận xét khai báo Lớp A từ Chương trình B, nhưng vì dòng B mới, dòng này vẫn ổn, cho phép thay A.ivào đó là tham chiếu 2giá trị từ Chương trình A. Cờ Trình biên dịch làm cho Chương trình chạy B.Main () vì A.Main () cũng tồn tại. Kết quả là Chương trình A + B không đưa ra đối số của nó, mà thay vào đó, đi đến phân đoạn sau của B.Main (), về cơ bản chỉ là quine C # tiêu chuẩn .


1
"các chương trình mèo ... cần sao chép stdin vào thiết bị xuất chuẩn"
Jakob

9

Haskell , 116 + 20 = 187 175 174 136 byte

Một bó byte được lưu kể từ khi Ørjan Johansen chỉ cho tôi interact

Cát 1

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

Hãy thử trực tuyến!

Cát 2

main|1>0=interact id

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!


Nguyên tắc cơ bản trong công việc ở đây là khi chúng ta thêm con mèo thứ hai vào con đầu tiên, chúng ta thay đổi tên của hàm mà chúng ta đang tương tác từ ađến idmain. Vì interact idlà một con mèo, chúng tôi muốn idmaincho tôi một chức năng trả về một quine. Giải pháp rõ ràng sẽ là sử dụng const, tuy nhiên vì chúng ta có thể giả sử đầu vào cũng (++)hoạt động trống . Từ đây, chúng tôi tìm thấy mã nguồn thông qua các phương tiện khá chuẩn, chúng tôi có một biến gmã hóa nguồn và chúng tôi sử dụng một trình bao bọc đặc biệt để in nó ở dạng chuỗi và dạng mã. Có một ngoại lệ nhỏ là chúng ta cần đặt bộ mã hóa ở phía trước vì chúng ta đã cần kết thúc interact id. Điều này có nghĩa là thêmg=không được mã hóa và phải được xử lý thủ công. Con mèo tiếp theo của chúng tôi khá chuẩn, ngoại trừ chúng tôi cần tạo mã hợp lệ khi xử lý đến cuối con mèo khác, vì vậy chúng tôi cần cả hai con mèo làm ví dụ của những người bảo vệ mẫu.

Chiến lược thay thế, 43 + 105 = 186 148

Cát 1

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

Hãy thử trực tuyến!

Cát 2

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

Hãy thử trực tuyến!

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="

Hãy thử trực tuyến!


1
Bạn có thể rút ngắn khá nhiều bằng cách thay getContents+ putStrbằng interact id. Hãy thử trực tuyến! (Quine không còn hoạt động với đầu vào không trống, cho phép sử dụng một (++ ...)phần cho idmain.)
Ørjan Johansen

@ RjanJohansen Cảm ơn! Tôi không biết interact, tôi đoán đó là vì tôi hiếm khi làm công cụ IO với Haskell. Tôi đã chỉnh sửa bài viết.
Thuật sĩ lúa mì

8

Python 3, 286 byte

Golf Python đầu tiên của tôi và quine đầu tiên của tôi! Không thanh lịch, nhưng nó hoạt động.

Chương trình 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()));

(không có dòng mới)

Chương trình B (48 byte)

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

(không có dòng mới)

Dùng thử trực tuyến

Lời cảm ơn

  • -24 byte nhờ Jo King
  • -82 byte nhờ Jo King

Bạn có thể làm end=open...và sử dụng %rthay vì %skhông phải thực hiện dòng mới và trích dẫn
Jo King

Thật tuyệt, tôi chuyển sang %r. Không chắc chắn những gì bạn có ý nghĩa về dòng mới mặc dù.
Jakob

1
Thay vì %sđịnh dạng một dòng mới, bạn chỉ có thể thực hiện theo nghĩa đen \n. Bạn cũng có thể sử dụng ;để phân tách các câu lệnh thay vì \n(ngoại trừ các ifnhu cầu nằm trên dòng riêng của nó). %có thể được thoát trong chuỗi bằng cách làm %%. Đối số duy nhất cần thiết để định dạng chuỗi là chính chuỗi đó, mọi thứ khác có thể bị sọc
Jo King

1
Chương trình B (và văn bản cho nó) có thể sử dụng locals()để lưu 2 byte.
Jonathan Allan

6

C ++ (tiếng kêu) , 313 + 102 = 415 byte

Chương trình A (kết thúc trong một dòng mới):

#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);})

Chương trình B (không kết thúc trong dòng mới):

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

Không phải là lén lút khủng khiếp, và như thường lệ, C ++ không phải là tuyệt vời để khai thác. Tôi sẽ không ngạc nhiên nếu có nhiều cách để cạo byte ở đây và cùng một ý tưởng. Một nhược điểm nhỏ là thay đổi hành vi của một cái gì đó sau khi nó được xác định và một trình khởi tạo biến động với hiệu ứng phụ thực hiện thủ thuật. (Điều này thậm chí có thể được thực hiện trong C mà không cần phần mở rộng trình biên dịch không?)

Dùng thử trực tuyến: A , B , AB

(Mối quan tâm duy nhất về tính di động mà tôi biết là chương trình giả định <cstdio>đặt tên cả trong không gian tên toàn cầu và trong std.)


5

Befunge-98 (FBBI) , 8 + 15 = 23 byte

A + B: (chỉ hoạt động khi không có đầu vào)

+9*5~,#@#@~,9j>:#,_:@#"

Hãy thử trực tuyến!

A:

+9*5~,#@

Hãy thử trực tuyến!

B:

#@~,9j>:#,_:@#"

Hãy thử trực tuyến!


Tôi đã tự hỏi nếu ai đó sẽ quản lý một câu trả lời befunge. Thật tệ khi cái này không phải là 2D: - /
Beefster

@Beefster vâng. Vấn đề là thật khó để thực hiện Quine 2d. Có lẽ tôi sẽ làm việc với một cái gì đó
MildlyMilquetoast

5

Python 3 , 100 + 37 = 137 byte

Chương trình A:

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

Hãy thử trực tuyến!

Chương trình B:

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

Hãy thử trực tuyến!

Làm 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)

Hãy thử trực tuyến!

Chỉ hoạt động khi đầu vào trống, nếu không nó sẽ đưa đầu vào vào đầu ra.


Các trích dẫn kép nên là những người duy nhất.
Jonathan Allan

Tai nạn được phép?
Jakob

@Jakob Câu hỏi không nói rằng sự cố không được phép và thông thường đầu ra cho STDERR bị bỏ qua
Jo King

Được rồi. Phím tắt thông minh!
Jakob

4

Tùy viên , 15 + 126 = 141 byte

A:

AllInput[]|Echo

Hãy thử trực tuyến!

B:

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!

Giải trình

Mỗi chương trình mèo mã hóa AllInput[]|Echo, đó là một chương trình mèo đơn giản. B là pha quine chính; một mình, nó là một hàm vectơ (thông qua unary @) được gọi mà không có đầu vào (được gọi là |Call). Vì vậy, các điều kiện đầu tiên If[_,A,B]thực hiện B, đó là đơn giản AllInput[]|Echo.

Khi A + B được thực thi, unary @trở thành nhị phân @do Echohợp nhất với lambda:

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

Bây giờ, điều này có nghĩa là lambda được thực hiện trước đó Echolà. Quay lại điều kiện, hàm này hiện có tất cả STDIN làm đối số. Vì vậy, If[_,A,B]thực thi A, đó là khung quine tiêu chuẩn.


3

Stax , 16 + 12 = 28 byte

Cát 1:

"yi|d|ca34b4lr"y

Chạy và gỡ lỗi nó

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

Cát 2:

i|d|ca34b4lr

Chạy và gỡ lỗi nó

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

Chạy và gỡ lỗi nó

"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

Cát 1:

Lua , 41 byte

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

Hãy thử trực tuyến!


Cát 2:

Lua , 70 byte

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

Hãy thử trực tuyến!


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

Hãy thử trực tuyến!

io.input(arg[0]) trong Cat 2 đặt tệp hiện tại làm đầu vào tiêu chuẩn và kết quả là con mèo in mã nguồn


1
Chào mừng bạn đến với PPCG
Muhammad Salman

Bạn có thể lưu một byte trong cat 1 bằng cách xóa dấu chấm phẩy cuối cùng?
Muhammad Salman

1
Thật không may, đọc các tập tin hiện tại là một lỗ hổng tiêu chuẩn. Nhưng dù sao cũng cố gắng.
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()

Hãy thử trực tuyến!

Cát A, 57 byte


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

Hãy thử trực tuyến!

Cát 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()

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.