概念
编写一个程序,以其编程语言输出代码。该代码在执行时必须输出原始程序。
规则
- 由于这是一个骗子,您可以阅读原始源代码。
- 第一个输出程序必须使用与原始程序相同的语言。
- 您可能没有输出常规的奎因。这两个程序必须不同。
- 有标准漏洞。
- 这是代码高尔夫球,因此最短的答案会获胜,但是不会选择它。
编写一个程序,以其编程语言输出代码。该代码在执行时必须输出原始程序。
Answers:
第二个程序是
1个
第一个程序计算空输入(实际上具有区域0,但是该模式始终至少运行一次,以使程序决定要在空输入上打印的内容)上的空模式的匹配数。第二个程序以量词(如{1}
正则表达式中的)开头,这会导致解析错误。由于程序无法成功解析,因此STDOUT为空字符串。
7使用3位字符集,但是将输入打包成字节(根据meta,具有亚字节字符集的语言将使用字节数来计算磁盘上的文件)。这xxd
是该程序的转储:
00000000: 4cf4 L.
当将此文件提供给7解释器时,它将输出以下程序:
00000000: 4fa6 7f O..
然后,它将再次输出原始程序。
那么这是怎么回事?尽管可以说程序正在以另一种方式作弊,但没有涉及阅读源代码(实际上,我认为不可能在7中阅读源代码)。让我知道你的想法。该程序的工作原理如下。(请注意,每个7个命令都有两个变体,其中一些没有名称并且无法在原始程序中显示。总共十二个命令,分为六对。我对主动命令使用粗体,对于被动命令使用非粗体命令,并且在主动命令没有名称的情况下,我给它命名为与相应被动命令相同的名称,并依靠粗体来区分。在两者都被命名的情况下,例如7
,它是主动变体1
,每个命令都有自己的名称,粗体只是语法突出显示。)
231 7 23原始程序,解压成八进制 231将237推入堆栈 23推23到堆栈 (隐式)将堆栈顶部的副本附加到程序中 2 堆栈顶部重复(当前为23) 3 输出堆栈顶部,弹出第二个堆栈元素
至此,7解释器看到堆栈的顶部包含无法表示的命令(2
和3
),因此它逃离了堆栈的顶部,产生了723
(是)。第一个命令输出选择输出格式;在这种情况下,格式为7,“将输出格式设置为与程序相同”。因此,命令将输出打包为字节。然后程序继续:
231 7 23 23 (隐式)将堆栈顶部的副本附加到程序中 2 堆栈顶部重复(当前为237) 3 输出堆栈顶部,弹出第二个堆栈元素 7 将空元素推入堆栈
此时,堆栈上只有空的堆栈元素,因此程序退出。我们输出23
较早。如果我们进行转义237
(并且必须这样做,因为它包含无法代表的命令),我们将得到7231
。它直接获取输出,从而形成程序的最终输出237231
(格式与程序相同,即打包为字节)。那是4fa67f
。(可以注意到,1
就影响输出而言,完全没有意义;唯一的原因是使这两个程序不同。)
运行过程237231
几乎完全相同。区别在于,无用程序1
仅在第一次打印后运行(并且空元素在第二次到达程序的当前末尾时被隐式删除)。同样,231
最终输出本身,23
最终输出本身之前是7
,我们得到231723
了原始程序。
观察者可能会注意到,尽管这两个程序在语言的“本机”八进制中长度相同,但它们在磁盘上的长度却不同。这是因为可以用任意数量的1位填充7程序,而打包格式则丢弃尾随填充。编码的方式如下:
2 3 1 7 2 3
010011001111010011(1...)
4 c f 4 padding
换句话说,两个字节4C
F4
足以代表程序,所以这就是我所使用的全部。
非作弊:
A=''';print(("A="+("'"*3+A)*2).translate({65:66,66:65}))''';print(("A="+("'"*3+A)*2).translate({65:66,66:65}))
打印:
B=''';print(("B="+("'"*3+B)*2).translate({65:66,66:65}))''';print(("B="+("'"*3+B)*2).translate({65:66,66:65}))
执行时将打印原始程序。
1\n1\n
前段时间有一个聊天讨论,这暗示在RProgN中将是一个非作弊的quine,因为每个1相互打印(并且只有每个1本身都被打印才被视为作弊)。这实际上暗示的是,有时很难定义藜麦作弊。(但是,无论哪种方式,这个答案都是正确的,因为这个问题实际上并不需要骗子,而是允许这样做。)
1\n
技术上讲,RProgN 是有效的quine,1
不是常量,而是对推1
送到堆栈的函数的调用。
1q_a_q
运行时,输出:
q_a_q1
依次输出1q_a_q
。
1q_a_q
1 the digit one (ignored)
q the source code (ignored)
q the source code
_ reversed
a and outputted
_ and reversed (ignored)
q_a_q1
q the source code (ignored)
1 the digit one (ignored)
q the source code
_ reversed
a and outputted
_ and reversed (ignored)
(_0=_=>console.log(`(_0=${_0})()`.replace(/0/g,n=>+!+n)))()
输出:
(_1=_=>console.log(`(_1=${_1})()`.replace(/1/g,n=>+!+n)))()
-1字节(@ETHProductions):在正则表达式中使用0代替\ d
n=>1-n
代替n=>+!+n
。
1
最终将其替换为正则表达式。
rev $0 # 0$ ver
-3感谢@izabera
Bash
,Tac
和`版本?
rev $0 # 0$<space><space>ver
由于某种原因,我无法在评论中添加两个空格
tac
rev
-ed是cat
。