两只猫在奎因


30

挑战

制作两个程序A和B,它们都是相同语言的cat程序。连接时,AB(也应使用相同的语言)应该是一个喹。

例如,假设helloworld都是使用XYZ语言的cat程序。如果helloworld是所说语言的奎因,则您的解决方案有效。

对于那些不熟悉猫和奎因的人来说,猫程序是一种完全打印通过stdin给它的东西的程序,而奎因是一种可以打印其自己的源代码的程序。

计分和规则

  • 串联的AB程序的总字节数就是您的分数。因为这是代码高尔夫球,所以最低分获胜。
  • 禁止出现标准漏洞
  • 输入必须来自stdin,输出必须进入stdout。
  • cat程序不需要参数。他们只需要将stdin复制到stdout。
  • 当没有任何输入程序但没有必要为其他输入正确运行(但是可能)时,该程序应该起作用。
  • 如果仅打印一次源代码,仅需一次终止即可。
  • 至少需要一个字节长。
  • A和B可以是同一程序。
  • BA不必是密码子,甚至不必是有效的程序。

我认为您不应该让A和B可以使用相同的程序规则
Muhammad Salman

2
@MuhammadSalman我最初的想法是将猫程序加倍以变成奎因。我只是想为更简单的解决方案敞开大门,因为我并不完全确定是否有可能。看起来我在两个方面都错了,但是我很好。
Beefster

3
您可能应该添加一个AB非空值,因为许多语言都有一个0字节的cat允许0字节的quine。
DJMcMayhem

9
@DJMcMayhem 0字节的quine虽然不是有效的quine。
妮莎(Nissa)

4
什么是猫计划?
Pedro A

Answers:


32

V,2 + 2 == 4字节

2i2i

尝试奎因!

试试猫!

A2i

B也是2i

它是如何工作的?

首先,对V的工作原理进行一些解释。使这个答案成为可能的一个值得注意的事情是,在V中,空程序 cat程序。这不是特例,而是V工作方式所固有的。启动时,所有输入都加载到“缓冲区”中,每个命令都会以某种方式修改缓冲区,然后在程序完成后隐式打印缓冲区。这意味着NOP的任何字符串也是cat程序。

i命令表示进入插入模式,这意味着后跟的每个字符i都将添加到缓冲区中。前面有一个数字,该文本将重复n次。

这意味着对于cat程序,不会将任何内容添加到缓冲区,并且将在读取时将其打印出来。换一种说法:

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

但是对于quine,在i:之后有文字:

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

厚脸皮的不回答

V,0字节

在线尝试!

A是空程序。

B也是空程序。

:P


21
其他所有语言:噢,我们走到了死胡同!。V:*发布标准奎因*
暴民埃里克(Erik the Outgolfer)'18年

13

Ruby,71个字节

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

可以分为猫如下:

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

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

除了前导2之外,这两只猫是完全相同的,这在所有三个程序中都是无操作的。“” <<2是一个字符串,表示从下一行开始直到其行中的终止符2的所有内容都是字符串,我们将其连接到自身(*2)并附加一个尾随的2。因此正则表达式将不匹配它,我们将深入到该$<.read表达式并输出STDOUT。但是,一旦我们连接了猫,字符串将直到第三行才终止,因此正则表达式匹配,我们将短路并输出quine。


11

Pyth,29个字节(5 + 24) 27个字节(5 + 22)

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

那很有趣。
在这里
尝试奎因在这里尝试第一只猫在这里
尝试第二只猫

说明

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#编译器),551字节

A:95个字节

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

在线尝试!

B:438 + 18字节

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

在线尝试!

A + B:533 + 18字节

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

在线尝试!

A和B将输入作为命令行参数。A + B忽略任何输入。B和A + B上的18个字节被添加为/p:StartupObject=B发送到MSBuild 的选项。它仅在A + B上是绝对必要的,但是似乎欺骗B中也没有。

说明

程序A很简单。类A包含一个i初始化为的(未使用的)静态变量2,并在运行时输出其第一个参数。将//在年底是A + B的代码很重要,但确实没有在A本身。

程序B孤立地很奇怪,但是本质上是相同的。它创建一个类A,该类包含一个i初始化为的静态变量0,然后运行类B的Main方法,该方法与程序A相同,因为A.i它小于1,并在任何奇怪的东西之前返回。这里不需要换行,但对于A + B来说很重要。

组合使用时,//from程序A注释掉了程序B中的Class A声明,但是由于换行了Class B是好的,因此允许A.i引用2程序A中的值。编译器标志使程序运行B.Main(),因为A.Main()也存在。结果是程序A + B不输出其自变量,而是转到B.Main()的以下段,该段基本上只是标准C#quine


1
“猫程序...需要将stdin复制到stdout”
Jakob

9

Haskell中,116 + 20 = 187 175 174 136字节

自ØrjanJohansen向我展示以来,节省了一堆字节 interact

猫1

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

在线尝试!

猫2

main|1>0=interact id

在线尝试!

奎因

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

在线尝试!


这里工作的基本原理是,当我们在第二只猫上添加第二只猫时,我们将与之交互的函数的名称从ato 更改为idmain。既然interact id是猫,我们想idmain给我一个返回奎因的函数。显而易见的解决方案是使用const,但是由于我们可以假定输入也是空的,因此可以使用(++)。从这里我们可以通过相当标准的方式找到源代码,我们有一个变量g对源进行编码,并使用特殊的包装器以字符串形式和代码形式打印源代码。有一点例外,我们需要将编码器放在最前面,因为我们已经需要以结尾interact id。这意味着额外的g=没有编码,必须手动处理。我们的下一只猫是非常标准的,除了在粘贴到另一只猫的末尾时需要使它成为有效代码,因此我们需要两只猫都成为模式防护的实例。

替代策略,43 + 105 = 186 148

猫1

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

在线尝试!

猫2

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

在线尝试!


1
您可以通过更换缩短相当多的位getContents+ putStrinteract id在线尝试!(该队列不再适用于非空输入,允许在其中使用一个(++ ...)部分idmain。)
ØrjanJohansen

@ØrjanJohansen谢谢!我不知道interact,我想那是因为我很少用Haskell做IO东西。我已经编辑了帖子。
小麦巫师

8

Python 3,286个字节

我的第一个Python高尔夫和我的第一个奎因!不是很优雅,但是可以。

程序A(238字节)

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

(无尾随换行符)

程序B(48字节)

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

(无尾随换行符)

在线试用

致谢

  • -24字节,感谢Jo King
  • -82字节,感谢Jo King

您可以end=open...使用和使用%r而不是%s不必使用换行符和引号
Jo King

太酷了,我切换到%r。虽然不确定您对换行符的含义。
Jakob

1
除了%s格式化换行符外,您还可以执行literal \n。您也可以使用;而不是拆分语句\n(除非if需要单独行)。%可以通过在字符串中转义%%。格式化字符串所需要的唯一参数是字符串本身,其他一切可以条纹
乔金

1
程序B(及其文本)可用于locals()保存2个字节。
乔纳森·艾伦,

6

C ++(clang),313 + 102 = 415字节

程序A(以换行符结尾):

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

程序B(不以换行符结尾):

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

并不是很偷偷摸摸,而且像往常一样,C ++并不是那么好用。如果有相同的想法可以在任何地方剃掉字节,我不会感到惊讶。一个小问题就是在定义某物后改变其行为,而具有副作用的动态变量初始化器可以解决问题。(这甚至可以在没有编译器扩展的C语言中完成吗?)

在线尝试:ABAB

(我知道的唯一可移植性问题是该程序假定<cstdio>将名称同时放在全局名称空间和in中std。)



5

Python 3 + 37 = 137字节

程序A:

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

在线尝试!

程式B:

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

在线尝试!

使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)

在线尝试!

仅在输入为空时起作用,否则将输入添加到输出前。


双引号应为单引号。
乔纳森·艾伦,

允许崩溃吗?
Jakob

@Jakob的问题不说,崩溃是不是允许的,并且通常输出到STDERR被忽略
乔金

好,可以。快捷捷径!
Jakob

4

随员,15 + 126 = 141字节

A:

AllInput[]|Echo

在线尝试!

B:

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

在线尝试!

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

在线尝试!

说明

每个cat程序均可进行编码AllInput[]|Echo,这是一个简单的cat程序。B是主奎尼相;单独地,它是一个@没有输入(称为|Call)的矢量化函数(通过unary )。因此,第一个条件If[_,A,B]执行B,即AllInput[]|Echo

当执行A + B时,由于与lambda合并,一元@变成二进制:@Echo

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

现在,这意味着lambda在is之前执行Echo。回到条件,此函数现在将所有STDIN作为参数。所以,If[_,A,B]执行A,这是标准的奎因框架。


3

萨克斯,16 + 12 = 28个字节

类别1:

"yi|d|ca34b4lr"y

运行并调试

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

猫2:

i|d|ca34b4lr

运行并调试

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

运行并调试

"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

类别1:

Lua,41个字节

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

在线尝试!


类别2:

Lua,70个字节

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

在线尝试!


Quine:

Lua,111个字节

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

在线尝试!

io.input(arg[0]) 在Cat 2中,将当前文件设置为标准输入,因此,cat打印源代码


1
欢迎来到PPCG
穆罕默德·萨尔曼

您可以通过删除最后一个分号在cat 1中保存一个字节。
穆罕默德·萨尔曼

1
不幸的是,读取当前文件是一个标准漏洞。但是无论如何还是要尝试。
Beefster


0

JavaScript(Node.js),199字节


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()

在线尝试!

Cat A,57个字节


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

在线尝试!

Cat B,142个字节

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()

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.