给您锦上添花!


204

使用您的选择,打高尔夫球的语言奎因

是一个非空的计算机程序,其不采取任何输入,并产生它自己的源代码的副本作为其唯一的输出。

不作弊-这意味着您不能只读取源文件并打印它。同样,在许多语言中,空文件也是一个提包:也不被视为合法提包。

没有错误线索-错误线索已经存在一个单独的挑战

要点:

  • 最小代码(以字节为单位)
  • 最混淆/模糊的解决方案
  • 使用深奥/晦涩的语言
  • 成功使用难以打高尔夫的语言

以下堆栈摘录可用于快速查看每种语言的当前分数,从而了解哪些语言具有现有答案以及您要击败的目标类型:


4
您不是要说:“向您求助!
Mateen Ulhaq

50
@muntoo这是一部关于“学到Haskell的伟大成就”的剧本。
拉菲·凯特勒

Answers:


106

Hexagony,边长17 16 816个 705字节

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

在线尝试!

这是展开的样子:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

不错啊,这是相当的情感过山车......我停下来计数我之间“哈哈,这太疯狂了”和“等待,如果我做切换的次数,这个它实际上应该是相当可行的”。Hexagony的布局规则对代码施加的约束非常严重。

这可能是可以减少的边长1或2个不改变的一般方法,但它会很艰难(只有细胞#是当前未使用可用于解码器)。目前,对于如何使用一种更有效的方法,我也完全没有想法,但是我敢肯定有这种想法。在接下来的几天里,我会考虑一下,也许在我添加解释和所有内容之前,尝试打一个侧面。

至少,我已经证明这是可能的...

一些CJam脚本供我将来参考:


50
亲爱的皮特,这是什么。
科纳·奥布莱恩

2
花费了多长时间?
阿德南

3
@AandN从昨天开始,我时不时地在讨论通用的“模板”的概念(不涉及任何实际的测试……只是在7x7的网格上键入一些东西,看看它是否可行。我大概已经丢弃了六种方法)。然后,实际的编码花费了今晚的时间,大概是3个小时。
Martin Ender

9
无法用言语解释我是如何惊讶我在深奥的IDE一步一步的行动看到了这个时候...要谁可能想明白这一点,这六角编码“解码器”的一部分插入其中印有一个整数!,然后用/倒数第二行的镜像进入解码器,以打印解码器代码以完成quine。它具有神奇的用途,<并且>可以读取多行很大的整数并建立存储解码器的区域。我真的很想知道正在考虑哪些“数十种方法”?
阳光明媚的双关中

3
说明?---
MD XF

77

MySQL,167个字符

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

那就对了。:-)

我确实确实自己写过这个。它最初发布在我的网站上


72

GolfScript,2个字节

1

(注意尾随换行符)这会将数字1压入堆栈。在程序结束时,GolfScript打印出堆栈中的所有项目(中间没有空格),然后打印换行符。

这是一个真正的quine(如问题中所列),因为它实际上执行了代码。它不只是“读取源文件并打印”(与PHP提交不同)。


再举一个例子,这是一个可以打印的GolfScript程序12345678

9,(;
  1. 9:将9推入堆栈
  2. ,:使用9作为参数,将数组推入[0 1 2 3 4 5 6 7 8]堆栈
  3. (:使用数组作为参数,将数组[1 2 3 4 5 6 7 8]和项目推入0堆栈
  4. ;:丢弃栈顶项

堆栈现在包含数组[1 2 3 4 5 6 7 8]。这将被写入标准输出,元素之间没有空格,后跟换行符。


18
或PowerShell或PHP :-)
Joey

6
您没有时光倒流给发明者发明GolfScript的想法,是吗?
Mateen Ulhaq

77
从技术上讲,1它不是GolfScript中的一个quine:它输出1\n,其中\n表示换行符。但是,两字符程序1\n 一个奎因。
Ilmari Karonen '02

17
单字符程序\n大概也是吗?
林恩

10
@Pseudonym quine实际上是一个打印其自身源代码的程序。我认为“结构”没有任何随意的限制。
Hugo Zink

71

Brain-Flak9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488字节

现在适合可观察的宇宙!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

在线尝试!


说明

这个Quine就像大多数密宗语言的Quines一样;它有两个部分:编码器和解码器。编码器在开头是所有括号,而解码器在最后是较复杂的部分。

编码程序的一种简单方法是将解码器中每个字符的ASCII值放入堆栈。这不是一个好主意,因为Brain-Flak仅使用8个字符(()<>[]{}),因此您最终要花很多字节来编码很少的信息。一个更聪明的想法,到现在为止用尽的一个想法是将8个花括号中的每一个都分配给一个较小的数字(1-8),并使用我们的解码器将它们转换为ASCII值。这很好,因为与以前的252相比,编码字符的花费不超过18个字节。

但是,此程序都不会。它依赖于Brain-Flak程序都被平衡以对8个大括号进行编码的事实,其数字最多为5。对它们的编码如下。

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

所有接近的括号都被分配为1,因为我们可以使用上下文来确定在特定情况下需要使用哪个括号。这听起来像Brain-Flak程序的艰巨任务,但实际上并非如此。以下列编码为例,以下括号被解码,而括号被替换为.

(.
((..
<([.{...

希望您能看到算法非常简单,我们从左到右阅读,每次遇到开括号时,我们都将其闭括号推到一个虚构的堆栈中,当遇到a时,.我们弹出最高值并将其替换为.。这种新的编码为我们节省了编码器中的大量字节,而仅使我们在解码器上损失了少数字节。

低级解释

工作正在进行中


25
我认为您将赢得最长的解决方案,以应对代码高尔夫挑战……
Mego

18
刚刚成为PPCG Nope 历史上最大的单场高尔夫9.8e580仍然令人印象深刻。
丹尼斯

19
+1以适合可观察的宇宙。另外,对于TIO Nexus,固定链接应该适合答案。tio.run/nexus/…–
丹尼斯

3
...非常大的高尔夫球...
可破坏柠檬

3
我认为您会赢得大部分字节的胜利
Christopher

68

前奏5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 133字节的

感谢Sp3000节省了3个字节。

这相当长……(好吧,它仍然很长……至少在这个挑战上它击败了最短的Brainfuck C#quine),但这是我发现自己的第一个quine(我的Lua和Julia提交实际上只是标准的quine技术翻译成其他语言)据我所知,到目前为止,还没有人在Prelude中写过quine,所以我为此感到非常自豪。:)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

这么多的数字只是核心代码的编码,这就是为什么卷轴这么长的原因。

已使用此CJam脚本生成了编码该Quine的数字。

这需要一个符合标准的解释器,该解释器将打印字符(使用值作为字符代码)。因此,如果您使用的是Python解释器,则需要进行设置NUMERIC_OUTPUT = False

说明

首先,关于Prelude的几句话:Prelude中的每一行都是一个单独的“语音”,用于操纵自己的堆栈。这些堆栈被初始化为无限的0。该程序逐列执行,其中列中的所有命令根据先前的堆栈状态“同时”执行。将数字分别压入堆栈,因此42先按a 4,再按a 2。无法直接推送更大的数字,您必须将它们加起来。可以使用v和从相邻堆栈中复制值^。Brainfuck样式的循环可以用括号引入。有关更多信息,请参见标题中的链接。

这是奎纳的基本概念:首先,我们将数字负载推入对奎纳核心编码的堆栈。然后,所述核心获取这些数字,对它们进行解码以自行打印,然后打印出现在代码中的数字(以及结尾处的数字))。

由于我必须将内核分成多行,因此这有点复杂。最初,我在一开始就进行了编码,但是随后需要在其他行上填充相同数量的空格。这就是为什么初始分数都那么大的原因。现在,我将编码放在最后,但这意味着我首先需要跳过核心,然后按数字,然后跳回到开头并进行打印。

编码

由于代码仅具有两种声音,并且和邻接是循环的,^并且v是同义词。很好,因为它v具有迄今为止最大的字符代码,因此始终使用它可以避免^使编码变得更简单。现在,所有字符代码的范围都在10到94(含)之间。这意味着我可以用正好两个小数位编码每个字符。但是,存在一个问题:某些字符(尤其是换行符)的十进制表示形式为零。这是一个问题,因为很难从堆栈底部区分零。幸运的是,有一个简单的解决方法:我们将字符代码偏移2,因此我们的范围是12到96(含),仍然可以舒适地容纳两个小数位。现在,在Prelude程序中可以出现的所有字符中,0它的表示形式为0(50),但我们实际上根本不需要0。这就是我使用的编码,逐个推每个数字。

但是,由于我们正在使用堆栈,因此表示被反向推送。因此,如果您看一下编码的结尾:

...9647344257

分成两对并反向,然后减去两个,然后查找字符代码:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

where 32是对应于空格。核心完全执行此转换,然后打印字符。

核心

因此,让我们看一下这些数字是如何实际处理的。首先,请务必注意,匹配的括号不必在Prelude中位于同一行。每列只能有一个括号,因此括号之间没有歧义。特别是,右括号的垂直位置始终无关紧要-检查堆栈以确定循环是否终止(或完全跳过)的堆栈将始终是具有的堆栈(

我们想精确地运行两次代码-第一次,我们跳过核心,并在末尾推送所有数字,第二次,我们运行核心。实际上,在运行内核之后,我们将再次推送所有这些数字,但是由于循环此后终止,所以这是无关紧要的。这给出了以下骨架:

7(
  (                   )43... encoding ...57)

首先,我们将a推7到第一个声音-如果我们不这样做,我们将永远不会进入循环(对于骨骼,重要的是它必须为非零...为什么要特别注意,7我们稍后再介绍) 。然后我们进入主循环。现在,第二个声音包含另一个循环。在第一次通过时,将跳过此循环,因为第二个堆栈为空/仅包含0。因此,我们直接跳转到编码并将所有这些数字压入堆栈。将7我们推到第一堆栈仍然存在,因此该循环重复。

这次,7第二个堆栈上还有一个,因此我们在第二个语音上输入了loop。第二个语音上的循环经过设计,以使堆栈最后再次为空,因此它仅运行一次。这将消耗第一栈......所以,当我们离开环路上的第二个声音,我们再次推动所有的数字,但现在的7第一个堆栈上已被丢弃,所以主循环结束并且程序终止。

接下来,让我们看一下实际内核中的第一个循环。用(或同时执行操作)非常有趣。我在这里用=以下标记了循环体:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

这意味着包含的列(不被视为循环的一部分(即使跳过循环,该字符也仅执行一次)。但是包含的列) 循环的一部分,每次迭代都运行一次。

因此,我们从single开始-,它将7第一个堆栈上的内容-7再次转换为...,之后再进行介绍。至于实际的循环...

循环继续进行,而数字堆尚未清空。一次处理两位数字。此循环的目的是解码编码,打印字符,并同时将数字堆栈移至第一个语音。所以这部分首先:

^^^
#^#

第一列将1位数移到第一声音。第二列将10位数字复制到第一语音,同时还将1位数字复制回第二语音。第三列将复制的内容移回到第一个声音。这意味着第一个声音现在有两次1位数字,中间有10位数字。第二个声音只有另一个10位数的副本。这意味着我们可以使用堆栈顶部的值,并确保第一个堆栈上还有两个副本供以后使用。

现在我们从两个数字中恢复字符代码:

2+8+2-!
(1- )#

底部是一个小循环,仅将10位数递减为零。对于每个迭代,我们想在顶部添加10。请记住,第一个2不是循环的一部分,因此循环主体实际上+8+2是添加10(使用2先前的推入),而将另外2推入。因此,当我们完成循环后,第一个堆栈实际上具有基数- 10值和另一个2。我们用减去2 -以解决编码中的偏移量,并使用来打印字符!。在#刚刚底部循环结束丢弃为零。

此循环完成后,第二个堆栈为空,第一个堆栈以相反的顺序保存所有数字(-7底部为a)。其余的很简单:

( 6+ !
8(1-)8)#

这是核心的第二个循环,现在将回显所有数字。为此,我们需要对每个数字输入48位以获取其正确的字符代码。我们使用一个简单的循环来执行此操作,该循环运行8时间并6每次添加一次。结果!将显示8为,最后是下一次迭代。

那么-7呢?是的,48 - 7 = 41这是的字符代码)。魔法!

最后,当我们完成该循环时,我们丢弃8刚刚推送的,#以确保将外部循环留在第二个声音上。我们再次按下所有数字,程序终止。



19
马丁,你得停在某个地方。
seequ 2016年

3
我喜欢这总共打了5000多个字节,另外还要感谢Sp3000节省了3个字节。
卡米尔·德拉卡里

2
@KamilDrakari虽然那是最后3个字节,所以这是一个很大的问题。;)
马丁·恩德

57

六边形,边长11,314字节

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

在线尝试!


旧版本:

六边形,边长11,330字节

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

在线尝试!

编码器:在线试用!

该程序大致等效于以下Python代码:在线尝试!

展开的代码:

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

2 .s需要1位。其他任何字符都使用1位和一个以97为基数的数字。

说明

单击图像放大。每个说明部分都有相应的Python代码以帮助理解。

数据部分

除了让IP通过下半部分<"而不是在其他一些答案(带有和其他内容)中使用复杂的结构。

数据

首先,IP运行很多数字,无操作(.)和镜像(\)。每个数字都附加到存储器中的数字之后,因此最后存储器值等于程序开始时的数字。

mem = 362003511...99306179

! 打印它

stdout.write(str(mem))

$跳过下一个>

从开始<。如果内存值mem不正确(<= 0mem > 0不满足条件),则我们已经完成了程序的打印,应该退出。IP将遵循较高的路径。

出口

(让IP 在命中(终止程序)之前在世界范围内运行约33个命令,@因为将其放置在其他位置会产生一些额外的字节)

如果是真的,我们将遵循下面的路径,进行几次重定向,并在遇到其他条件之前执行更多命令。

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

现在内存看起来像这样:

记忆1

如果值为真:

if b > 0:

执行以下代码:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

见的详细解释Q4MartinEnder的HelloWorld的Hexagony答案。简而言之,此代码打印.两次。

本来我打算将此打印.一次。当我提出这个.想法(打印两次)并实现它时,节省了大约10位数字。

然后,

b = mem // a                # :

这是我意识到为我节省了大约14位数字的一个重要事实:您不需要在开始的地方。


为了理解我的意思,让我们来个BF类比。(如果您已经理解,请跳过此步骤)

给定代码

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

假设我们a是当前单元格b的值,是右单元格的值,则将其直接转换为BF是:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

但是,请注意,在程序执行过程中,我们不必一直处于同一位置。我们可以让值a等于每次迭代开始时的值,然后得到以下代码:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

短了几个字节。


此外,转角缠绕行为还使我免于在\那里拥有一面镜子-没有它,我将无法容纳数字(其\自身为+2位,.而其右侧为unpaired则为+2位,更不用说标志)

(细节:

  • IP进入左下角,朝左
  • 它扭曲到右上角,仍然朝左
  • 它遇到一个\反映它的东西,现在它朝上
  • 它进入角落并再次翘曲至左下角


如果(上面的mod 2操作的)值是falsy(零),则我们遵循以下路径:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

我不会在这里解释得太详细,但是偏移量实际上并不完全相同33,但与33mod 完全一致256。并chr具有隐式% 256


3
伙计,这是很多无人操作的事
Jo King

25
我笑道:“为了理解我的意思,让我们进行一个[BrainFuck]比喻。” 仅在PPCG ...上:)
Lynn

2
我像滚动了3遍,在答案的顶部对其进行了
投票

2
通过利用缩短数字的新空间来获得310个字节
Jo King

2
通过占用更多空间来占用308个字节
Jo King

46

Vim,11个字节

q"iq"qP<Esc>hqP
  • iq"qP<Esc>:手动插入必须在录音之外的文本副本。
  • q"hqP:将内部直接记录到未命名的""寄存器中,以便将其粘贴在中间。的h是唯一需要的重新定位; 如果将其放在宏中,它将被粘贴到结果中。

编辑

关于使用记录的注意事项q":未命名的寄存器""是一件很有趣的事情。它不是真正的寄存器,因为文本没有存储在其中。它实际上是指向某些其他寄存器的指针(通常"-用于不带换行符的删除,"0扬扬声号或"1带换行符的删除)。q"违反规则;它实际上写入"0。如果您""已经指向以外的其他寄存器"0q"则将覆盖"0""保持不变。当您启动一个新的Vim时,会""自动指向"0,因此在这种情况下就可以了。

基本上,Vim既怪异又马车。


等待,为什么这对我不起作用
破坏的柠檬

@DestructibleWatermelon不能肯定地说,但是最有可能一种解释。可能应该在撰写文章之前就使用它,因为它可能会使人失望。阅读编辑。
udioica

您可能应该提出一些有关如何y在跑步前进行按压或有所帮助的事
破坏的柠檬

为什么不习惯按<Esc>键显示?此Unicode块“控制图片”的一部分
mbomb007 '16

4
@ mbomb007该<Esc>符号在Vim映射(:help <>)中是标准的,这就是vimgolf.com使用的名称。任何有经验的vimgolfer都会用来阅读它。至于unicode,我不得不斜视阅读小写字母,它们使键入它们和搜索帮助文件的方法变得晦涩。
udioica

44

Cubix,20个字节

3434Qu$v@!<"OOw\o;/"

几乎得到了 \o/ ...

净额

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

在线尝试

在这里尝试!

补充笔记

背景故事

在阅读完@ ais523的出色回答后,我开始考虑进一步打球。毕竟,那里有很多无人值守的地方,感觉并没有那么压缩。但是,由于他的答案(以及我的答案)使用的技术要求代码跨越整行,因此至少需要节省12个字节。他的解释中有一句话确实使我思考:

在进一步打高尔夫球时,需要用其他方法来表示立方体的顶面。

然后,突然,当我站起来走开去喝点东西时,我大吃一惊:如果程序不使用字符代码,而是使用数字来代表顶面怎么办?如果我们要打印的数字有2位数字,这特别短。Cubix影院有推双位数3单字节指令:NS并且Q,这推动103234分别,所以这应该是相当golfy,我想。

这个想法的第一个复杂之处在于,顶面现在被无用的数字填充,因此我们不能再使用它了。第二个复杂性是,顶面的大小是立方体大小的平方,并且必须具有偶数大小,否则一个数字也将以指令指针的起始位置结尾,从而导致堆栈被污染。由于这些复杂性,我的代码需要适合大小为2的多维数据集(可以包含“仅” 24个字节,因此我必须至少保留21个字节)。另外,由于顶面和底面不可用,因此我只有16个有效字节。

因此,我首先选择了将成为顶面一半的数字。我从N(10)开始,但是由于我要打印所有内容而采用的方法并没有完全解决。无论哪种方式,S由于某种原因,我都重新开始并使用了(32)。那确实导致了适当的奎因,或者我想。一切都很好,但引号丢失了。然后,我想到Q(34)真的很有用。毕竟,34是双引号的字符代码,这使我们能够将其保留在堆栈上,从而节省(在我当时使用的布局中为2)珍贵的字节。在我稍微更改了IP路由之后,剩下的只是一项锻炼来填补空白。

这个怎么运作

该代码可以分为5部分。我将一一介绍。请注意,由于堆栈模型是先进先出的,因此我们以相反的顺序编码中间面。

第1步:打印顶面

无关的指令已由无操作(.)代替。IP从最左边的第三行开始,指向东方。堆栈(显然)是空的。

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

IP终止于第四行最左端的位置,指向西,即将绕到同一行的最右端。执行的指令是(没有控制流字符):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

堆栈仅包含34个,代表源的最后一个字符。

步骤2:对第四行进行编码

这几乎完成了您期望的工作:对第四行进行编码。IP从该行末尾的双引号开始,然后向西推,同时推送其落入的每个字符的字符代码,直到找到匹配的双引号为止。匹配的双引号也是第四行的最后一个字符,因为IP到达左边缘时会再次换行。

实际上,IP已向左移动了一个位置,并且堆栈现在包含了以字符代码和相反顺序表示的第四行。

步骤3:输入其他报价

我们需要再加上一个引号,还有什么比Q从正确的方法开始在程序开始时回收回收更好的方法呢?IP具有直接添加到对第三行进行编码的引号的附加好处。

这是此步骤的网络版本。#出于说明目的,无关紧要的指令再次被替换为no-op,执行的no-op被替换为井号(),并且IP从第四行的最后一个字符开始。

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

IP在第一条指令的第三行结束,因为它指向西,所以要包装到该行的末尾。执行以下指示(不包括控制流):

$uQ
$u  # Don't do anthing
  Q # Push the double quote

此双引号表示第三行末尾的引号。

步骤4:对第三行进行编码

该步骤与第2步完全相同,因此请在此处进行解释。

步骤5:打印堆栈

现在,堆栈包含第四行和第三行(以相反的顺序),因此我们现在需要做的就是打印它。IP从第三行的倒数第二条指令开始,向西移动。这是多维数据集的相关部分(同样,不相关的部分已由no-ops代替)。

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

正如您可能已经看到/预期的那样,这是一个循环。主体是:

o;
o  # Print top of stack as character
 ; # Delete top of stack

如果顶层项目为0,则循环结束,仅当堆栈为空时才会发生。如果循环结束,@则执行,结束程序。


希望我能对此再
投票一次

永远欢迎赏金;-)
路加福音

42

Javascript ES6-21个字节

$=_=>`$=${$};$()`;$()

我称这个奎因为“ The Bling Quine”。

有时,您需要打高尔夫。


会为!$=_=>`!$=${$}()`()您节省2个字节吗?
Downgoat

Invalid assignment left hand side。希望它有用:(
Mama Fun

1
@TùxCräftîñg消除模板文字周围的括号仅适用于本机原型函数,例如Array.prototype.join
Mama Fun Roll

2
嗯,不确定。我是一年多以前写的(当时被认为是有效的),但是我并没有太仔细研究奎因规则的变化。但是,在箭头功能上添加alertconsole.log之后并将模板字符串包装在括号中将起作用。
Mama Fun Roll

3
另外,如果您在concol中运行此命令,它将覆盖此站点上的$(jQuery函数),并且upvote函数将不再起作用。:)
史蒂文·帕林卡斯

41

Brainf * ck(755个字符)

这是基于Erik Bosman(csj.vu.nl的ejbosman)开发的技术。注意“ ESultanik的Quine!” 文本实际上是成为quine所必需的!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]

13
这是一个聪明的方法。
彼得·奥尔森

13
它是如何工作的?
自豪的haskeller 2014年

3
@proudhaskeller IIRC,之前的部分ESultanik's Quine!将内存设置为堆栈编码ESultanik's Quine!并向前,每个字符有两个字节的内存(ASCII值从0x1F开始偏移)。代码的最后一部分在内存中循环,首先以编程方式++>+++…为每个字符重新生成代码,然后实际打印字符。
ESultanik '16

4
@CatsAreFluffy他们必须是奎因!尽管确实可以删除它们,但还必须更改前面的代码以维护quine属性。
ESultanik '16

1
确实如此。换行符也是必需的。
CalculatorFeline

36

Hexagony,边长15 14 13 12 616个533 456 383字节

经过几天的仔细打高尔夫球,重新排列循环并重新开始,我终于设法将其降低到12边形的六边形。

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

在线尝试!

展开:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

尽管它看起来并不是最喜欢的六角形代码,但我使用的编码类型已针对较长时间的无操作进行了优化,否则您将避免这种情况。

说明

通过以不同的方式编码no-ops()来击败以前的Hexagony答案.。虽然这个答案通过使所有其他字符节省空间.,我的编码无操作的。这也意味着来源不必受到如此限制。

在这里,我使用基本的80编码,其中16以下的数字表示无操作,而16到79之间的数字表示32(!)至95(_)的范围(我现在才意识到我将所有_s打出代码大声笑)。一些Pythonic伪代码:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

该数字编码在六边形的前半部分,所有

" " > 
 " " > 
  ... etc

在左侧和

 > ,
< "
 >
< "
... etc

在右侧重定向指针以将数字编码为一个单元格。这是从马丁·恩德Martin Ender)的答案(谢谢)中获得的,因为我想不出一种更有效的方法。

然后通过进入底部->

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!'在开始循环之前,先打印数字并导航到右侧的存储单元。P='%将当前数字修改为80。如果结果为0,则向上移动到终止点@,否则向下移动,并在该结果旁边创建一个值为的单元格-16

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

将单元格设置为(mod值+ -16)。如果该值为负,则在分支处上升>+'\,否则下降。

如果值为正:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

指针最后指向,;-<该位置将单元格设置为(mod值--16)并进行打印。

该值为负:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

转到> ) <开始循环的部分。这里是孤立的:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

它执行'Q4;="=打印a 的代码.(再次感谢Martin Ender,后者编写了一个程序来查找字符的字母数字组合),然后移回起始单元格。然后,它递增())mod值单元格并再次循环,直到mod值为正。

完成此操作后,它将向上移动并与位于以下位置的另一部分合并:

 " " > . / < $ ; - < . . .
            \
             \

然后指针再次返回到较大循环的起点

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

执行='=:'该操作,将当前数字除以80,然后导航到正确的单元格。

旧版本(边长13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

在线尝试!

我绝对可以在这方面打另外一段距离,但是我要等到明天再说,因为天色已经晚了。原来我不耐烦,等不及明天。也许另一面可以打高尔夫球? :( ahhhhhhhhh我做到了!

我什至用基数为77的编码打了几个额外的数字,但这并不重要,因为它具有相同的字节数。


13
这真太了不起了。这种混合游程长度编码的想法确实很巧妙。:)如果我忘记了,请提醒我赏金。
马丁·恩德

35

PostScript,20个字符

简短而合法。20个字符,包括结尾的换行符。

(dup == =)
dup == =

33

Cubix,45字节

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

您可以在此处测试此代码。

该程序很难遵循,但是要有机会这样做,我们需要像Cubix解释器一样将其扩展为一个多维数据集以开始:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

这是一个Befunge样式的quine,它通过利用包装使字符串文字“环绕”可执行代码(仅带有一个"标记,该代码同时位于引号的内部和外部)而起作用,当您使用非线性和非平面程序)。请注意,这符合我们对适当的Quine的定义,因为两个双引号不会自行编码,而是稍后通过使用算术运算得出。

但是,与Befunge不同,我们在这里使用四个字符串,而不是一个。这就是它们被推入堆栈的方式。

  1. 程序从左边缘的顶部开始,向右移动;它向右转两次(R),使其沿环绕整个立方体的第三行和最后一行向左移动。双引号匹配自己,因此我们将整个第三行向后推到堆栈上。然后在双引号之后继续执行。

  2. u命令将向右掉头,因此我们要运行的下一件事是从'"中线开始。这将a "推入堆栈。继续环绕,我们击中<立方体左手边附近并弹回。从该方向接近时,我们看到的"不是简单命令,'"因此,整个第二行都在第三行和双引号上方向后推到堆栈上。

  3. 我们先将a压!入堆栈('!)并递增());这将产生一个双引号,而无需在我们的源代码中使用双引号(它将终止该字符串)。镜子(\)将执行方向向北反射;然后W命令回避到左侧。这使我们在第七列上向上移动,因为这是一个立方体,所以在第三行上向左环绕,然后在第三列上向下。我们按R,向右转,然后沿着第一行向左移动;然后$跳过R我们进入程序的过孔,因此执行将回绕到"行的末尾,然后以与第二和第三行相同的方式捕获字符串中的第一行。

  4. ^命令将我们向北发送至第11列,即第5列(允许进行多维数据集包装)向南。我们唯一遇到的是!(如果非零,则跳过;堆栈的顶部确实是非零),它跳过了该o命令,有效地使第五列完全为空。因此,我们返回到该u命令,该命令再次掉头,但是这次我们留在向南的最后一列,该命令向北绕到第四列。但是,在掉头期间我们将双引号引起来,因此我们从下到上捕获了字符串中的整个第四列。与程序中的大多数双引号不同,该引号不会自动关闭。而是由"右上角的封闭,这意味着我们捕获了9个字符的字符串...>.....

因此,堆栈布局现在是从上到下的:第四列;顶排 "; 中排 "; 底行。每一个都以最接近堆栈顶部的第一个字符表示在堆栈上(Cubix像Befunge一样以相反的顺序推动字符串,但是每次IP沿与自然读取方向相反的方向移动时,因此它实际上有效地反转了两次)。可以注意到,堆栈的内容几乎与原始程序相同(因为第四列和多维数据集的北/顶面以相同的顺序包含相同的字符;显然,它是故意设计的)。

下一步是打印堆栈中的内容。在所有推动之后,IP在第四列上向北移动,因此到达>该位置并进入一个紧密循环>>o;?(即“向东,向东,输出为字符,弹出,如果为正则向右转”)。因为第七行充满了NOP,所以?它将回绕到第一行>,因此这有效地压入了堆栈的全部内容(?在空堆栈上是空操作)。我们几乎打印了整个程序!不幸的是,还没有完成。我们在末尾缺少双引号。

循环结束后,我们将通过一对镜子反射到中心线,向西移动。(我们之前使用了\镜子的“另一面” ;现在我们使用的是西南面。/以前没有使用过镜子。)我们遇到'!,所以我们推了一个感叹号(即33;我们使用的是ASCII)而Cubix不会在整数和字符之间进行区分)。(方便地,这与之前!跳过该o命令所使用的命令相同。)我们遇到一对R命令,并使用它们进行“手动”掉头(R此处的第二个命令是较早使用的,以便到达第一个命令。行,因此在其R旁边放置另一个命令似乎是最自然的。W命令,回避到左侧。闪>退直接撞到第二行的命令中,使执行恰好回到原来的位置。因此,我们再次向左避开,但是这次我们要向南走,因此要执行的下一个命令是)(将感叹号增加到双引号中),然后是o(输出)。最后,执行沿第八行包装到第二列,在第二列中找到一个@退出程序。

对于第三行的错撇号,我表示歉意。在此版本的程序中,它不执行任何操作。这是我以前的想法的一部分,但事实证明这不是必需的。但是,一旦我有了一个有效的quine,我只是想提交它,而不是进一步弄乱它,尤其是删除它不会改变字节数。关于进一步深入研究这个问题,如果仅使用前五行在3×3的分辨率下做到这一点就不会令我感到惊讶,但是我看不出有明显的方法可以做到这一点甚至将所有控制流的压缩更紧密地打包在一起,并以其他某种方式表示多维数据集的顶面(或者修改算法,以便即使现在长度为十或十一个字符,它也可以继续使用第四列) 。


做得好,这是一个非常可观的成绩。我喜欢您编码顶面的方式。:)
马丁·恩德

这真是不可思议!如果有帮助,则另一种推送方式"Q
ETHproductions 2016年

1
哇!我从来没有见过cubix quine!
FlipTack

3
昨天我没有时间阅读说明,但是现在我有了...只是...哇。我不敢相信有两个或三个完全不同的目的使用了多少个字符。这可能是我见过的最酷的Cubix程序。
ETHproductions 2016年

很好的解释。
罗伯特·弗雷泽

33

Python 2,30个字节

_='_=%r;print _%%_';print _%_

从这里取


1
+1,您击败了我的类似解决方案,因此我将其删除。应当指出的是,这只是在Python 2.作品
nyuszika7h

2
变量名称为_,看起来很奇怪,但如果将其分配给任何字母,则读起来更好,例如s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury 2015年

5
如果此解决方案不是您自己创建的,则应将其设置为Community Wiki。此外,链接已死。
mbomb007 '16

1
我参加聚会有点晚了,但是有人可以解释一下这是如何工作的吗?
MadTux

9
这要求尾随换行有效。实际上,源代码与输出不匹配。
丹尼斯,

32

VIM,17,14次的击键

有人随机投票,所以我记得它存在。当我重新阅读它时,我以为“嘿,我可以做得更好!”,所以我打了两个字节。它仍然不是最短的,但至少是一种改进。


很长一段时间以来,我一直在想是否可以使用vim quine。一方面,因为vim即将完成,所以这必须是可能的。但是在寻找了很长一段时间的vim奎因之后,我找不到了。我确实发现了这个PPCG挑战,但是它是封闭的,而且与字面量的提法不完全相同。所以我决定做一个,因为找不到。

我真的为这个答案感到骄傲,因为有两个第一

  1. 这是我做过的第一根藜

  2. 据我所知,这是世界上第一个发布的vim-quine!我对此可能有误,因此,如果您知道其中之一,请告诉我。

因此,经过漫长的介绍,这里是:

qqX"qpAq@q<esc>q@q

在线尝试!

请注意,当您键入此内容时,它会将<esc>击键显示为^[。这仍然是准确的,因为^[表示了0x1B,这是ASCII形式的转义,并且vim内部表示<esc>密钥的方式。

请注意,如果加载现有的vim会话,则测试可能会失败。我写了一个答案,在这里解释说,如果您想了解更多信息,但是基本上,您需要使用以下命令启动vim

vim -u NONE -N -i NONE

qqq在运行之前键入。

说明:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

附带说明一下,这个答案可能是PPCG答案中大多数“ q”的世界纪录。


1
2i2i<esc>太近了 我觉得必须做些什么才能完成这项工作。
Zwei

@zwei我知道,很痛!实际上,<Esc>在V中是隐式的,因此可以工作。不幸的是,它还添加了换行符,这就是为什么我还没有发布它。
DJMcMayhem

q"iq"qbP<Esc>qbP是11。将其置于reddit之后,我在这里调查了vimgolfing并决定建立一个帐户。这是我在此处发布的答案。
udioica

2
@udioica您可以将其发布为答案吗?
DJMcMayhem

28

丢失120116 98 96 76 70 66字节

编辑:是,低于100

编辑:通过切换/到底行的全部s 保存了一堆字节

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

在线尝试!+ 验证对于所有可能的状态都是确定的

迷失是一种2D语言,其中开始位置和方向完全随机。这意味着在每个阶段都必须进行大量的错误检查,以确保您具有正确的指令指针,而这并不是随便徘徊的。

说明:

/底线的所有s都在此处,以确保沿垂直方向或底线产生的所有指针都沿正确的方向分布。从那里开始,它们最终到达几个不同的地方,但是所有这些最终都直接进入了

 ^%?>
 ////

清除堆栈中所有非零数字。在([该清除出任何额外0以及之后。

在清除的中间,它将击中%,这将关闭“安全性”,这将使程序在击中时结束@(否则,如果指针从处开始,则程序可能会立即结束@)。

从那里开始,它做了一个非常简单的2D语言quine,方法是"在第一行周围包裹一个字符串文字(),然后先将"空格(:2+)和换行符(52*)相乘,然后压入一个字符。在第二行中,它创建一个/字符(95*2+),并将其复制为一串(>::1?:[:[[[[),然后最终结束于@并隐式打印堆栈。该?1是从创建过多的0,如果指针最早进入,节省在具有后清除它们停止进程。

通过将最后一行都设为相同的字符,我在这里节省了20个字节,这意味着我可以直接从复制过程进入结尾@

有关复制过程的说明:

[是一个称为“门”的字符。如果指针碰到a [或a 的平坦侧面],它会反射,否则它会穿过它。每次指针与门互动时,它就会切换为相反的类型。利用这些知识,我们可以为一个指令在一个>:[块中执行多少次构造一个简单的公式。

添加初始数量的指令。对于每个[,在其左侧添加2倍的指令量。在示例中>::::[:[[[,我们以5作为初始金额。第一个门有4个重复指令,因此我们将4 * 2 = 8加到5得到13。其他三个门的左边有5个重复,所以我们将3 *(5 * 2)= 30加上13得到43执行dupe指令,>堆栈中有44 s。可以将相同的过程应用于其他指令,例如(将大量项目从堆栈中推入示波器或在此处使用以从堆栈中清除项目。

我在这里使用的一个技巧是避免重复太多0 1?。如果字符为0,?则不会跳过1,这意味着它将在重复项的其余部分重复1。这使得以后清除堆栈变得容易得多


25

这是SO中最短的两个Ruby quines :

_="_=%p;puts _%%_";puts _%_

puts <<2*2,2
puts <<2*2,2
2

不要问我第二个是如何工作的...


8
第二个使用heredoc,<<2在下一行开始一个字符串,然后*2重复该字符串
Ming-Tang

为什么需要2?
CalculatorFeline

1
@CalculatorFeline这是Heredoc字符串的终止符(必须出现在自己的行中)。它实际上不一定非要为2:tio.run / ## KypNqvz / v6C0pFjBxsZAy0jHgAuFY8D1 / z8A
Martin Ender

25

裂变,6个字节

现在看来,这是这些答案中最短的“正确”方法。

'!+OR"

说明

控制流从R单个向右(1,0)原子开始。它进入"切换打印模式,然后绕行,打印,'!+OR然后"再次命中并退出打印模式。

这样"就可以自行打印了。最简单的方法是'"O'"将原子的质量设置为的字符代码"O打印字符并销毁原子),但是如果我们这样做,"将会干扰打印模式。所以不是我们设置了原子的值'!(一个小于"),然后用增加+打印其结果O

备择方案

这里有一些替代方案,它们更长一些,但是也许他们的技术会激发人们使用它们来寻找更短的版本(或者在某些通用的奎因丝中它们会更有用)。

使用Jump 8字节

' |R@JO"

同样,代码从开始R。该@互换质量和能量给(0,1)。因此,J使原子跳过O直线到达原子上"。然后,像以前一样,除以外的所有内容"都以字符串模式打印。然后,原子撞击|以反转其方向,然后通过'"O印刷"。该空间有点烦人,但似乎很有必要,因为否则'会使原子将|a视为字符而不是镜像。

使用两个原子的8个字节

"'L;R@JO

它有两个原子,从左开始L,从右开始R。剩下的原子得到其值设置,'"然后立即将其打印O(并销毁该原子)。对于正确的原子,我们再次交换质量和能量,跳过,O以在打印模式下打印其余代码。之后,它的值由设置,'L但没关系,因为原子随后被丢弃;


由于源中缺少代码/数据分离,因此在技术上无效。
CalculatorFeline

4
@CalculatorFeline '!+编码"
Martin Ender'1

我对Fission不熟悉,但是可以|R@JO"'使用,或者在之后还需要那个空间'吗?
MildlyMilquetoast

1
@MistahFiggins我想是的,但更重要的是,您应该打印第'一个。
马丁·恩德

24

跨浏览器JavaScript(41个字符)

它可以在前5个网络浏览器(IE> = 8,Mozilla Firefox,Google Chrome,Safari,Opera)中运行。通过以下任意一种将其输入到开发者控制台中:

eval(I="'eval(I='+JSON.stringify(I)+')'")

它不是“作弊” —与Chris Jester-Young的单字节quine不同,因为可以很容易地对其进行修改以使用该alert()功能(花费14个字符):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

或转换为书签(成本22个字符):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")

24

C,64 60字节

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

到目前为止,这是已知的最短的C喹。这里有一个扩展的奖金,如果你找到一个较短。

这可以在POSIX环境中的GCCClangTCC中使用。它对所有这些调用过多的未定义行为。

只是为了好玩,这里有一个回购协议,其中包含所有的C基内斯我知道的。如果您发现或编写另一种在现有功能上添加了新功能和创意的功能,请随意进行分派/宣传。

请注意,它仅适用于ASCII环境。适用于EBCDIC,但仍需要POSIX。无论如何,祝您找到POSIX / EBCDIC环境的好运:P


这个怎么运作:

  1. main(s)滥用main参数,声明一个几乎没有类型的变量s。(请注意,这s实际上不是未键入的,但是由于列出的编译器会根据需要自动广播它,因此它可能*。)
  2. printf(s="..."设置s为提供的字符串,并将第一个参数传递给printf
  3. s设置为main(s){printf(s=%c%s%1$c,34,s);}
  4. %c设置为ASCII 34"。这使奎因成为可能。现在s看起来是这样的:
    main(s){printf(s="%s%1$c,34,s);}
  5. %s其设置为s自身,这可能是由于#2导致的。现在s看起来是这样的:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}
  6. %1$c被设置为ASCII 34 "printf第一个**参数。现在s看起来像这样:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ...恰好是原始源代码。

* 感谢@Pavel ** 示例
**格式说明符之后的第一个参数-在这种情况下为s。不可能引用格式说明符。


我认为用相同的方法将这种情况变得更短是不可能的。如果printf可以通过访问的格式说明符$,则该格式符适用于52个字节:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}

尽管当然不应该将其视为竞争,但1994年国际混淆C代码大赛1994_smr.c的“最糟糕的规则滥用”获胜者肯定要短一些。

@Ray不允许的。从任何定义来看,这都不是合适的方法。由于该程序,更改了查询规则:P
MD XF

我完全同意,但这是一个很有趣的技巧,即使有人出于历史原因,任何时候只要有人提到最小的已知奎因,都值得一提。

4
s属于类型int,而不是“无类型变量”。
feersum

2
这些编译器显然都允许将指针隐式转换为int。s=3显然不起作用,因为您需要将字符串两次传递给printf
feersum

24

Java,528字节:

具有原始方法的Java解决方案:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

可读形式:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}

它是如何工作的?
Loovjo 2015年

1
@Loovjo:与其他解决方案类似,该方法将代码分为两部分,然后插入整个String,这再次代表了代码的内部,但是整个代码不仅是String,而且还被编码为以36为底的长数字(26个字母字符+ 10数字)。
不明的使用者

1
如果您放进去if(++i==92),这可以缩短时间
tuskiomi

2
@tuskiomi:谢谢,缩短了两个字符
未知的用户

1
@userunknown实际上,a*由于数组在Java中不存在,因此为C。golf 的其他一些部分:import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}},其中abc是新计算出的幻数String。在java中8+它也可能改变class a{public static void maininterface a{static void main,并在Java中10+它也可以改变import java.math.*;BigInteger b=new BigInteger(var b=new java.math.BigInteger(
凯文·克鲁伊森

23

7

chicken

不,这不是直接呼应:)


该死的,你击败了我:)
塔科努特2014年

它没有回声,是字符串chicken
暴民埃里克(Erik the Outgolfer)

没有代码/数据分离,因此无效。
CalculatorFeline

10
@CalculatorFeline您阅读规则了吗?
Timtech '17

1
@JoKing我不认为这是无效的,因为质询的规则仅禁止零长度和作弊(读取您自己的源文件)quines。唯一禁止出现错误的现象的是标准漏洞 -除了通常不认为标准漏洞适用于早于它们的答案。
pppery

23

视网膜20 14 9 7字节

在开始之前,我想提到一个包含单个的文件的简单解决方案0。在这种情况下,Retina将尝试对0空输入中的s 进行计数,其结果也为0。我不会认为那是适当的选择。

所以这是一个合适的:

>\`
>\`

在线尝试!

或者,我们可以使用;代替>

说明

该程序由单个替换组成,我们将打印两次。

在第一行中,`分隔符将配置与正则表达式分开,因此正则表达式为空。因此,空字符串(即不存在的输入)被逐行替换为第二行。

要打印两次结果,我们将其包装在两个输出阶段。内部的一个\以换行符打印结果,外部的一个>不带换行符打印结果。

如果您对Retina有点熟悉,您可能想知道Retina的隐式输出发生了什么。视网膜的隐式输出通过将程序的最后阶段包装在输出阶段中而起作用。但是,如果最后阶段已经是输出阶段,那么Retina不会这样做。这样做的原因是,在普通程序中,能够用特殊字符(例如单个字节)\;单个字节替换隐式输出级(而不是也必须使用.标志来摆脱隐式输出级)更为有用。不幸的是,这种行为最终使我们花费了两个字节的费用。


20

Javascript(36个字符)

(function a(){alert("("+a+")()")})()

这是AFAICT,是迄今为止发布的最短的javascript quine。


1
那...真是令人印象深刻。您应该解释一下它对我的工作方式8- |
TehShrike 2011年

3
@TehShrike提示:您可以通过将功能强制为字符串来查看功能的内容。例如,如果您有一个函数a,则可以通过调用来访问其内容a.toString
彼得·奥尔森

7
但是,要想学究一点,如果您的JavaScript实现将函数字符串化的a方式与上面编写的完全相同,则这只是一个问题。但是,此代码的输出可能是任何JavaScript实现的关键。
Ilmari Karonen '02

1
这是同一个quine,短1个字节:!function a(){alert("!"+a+"()")}()
伊斯梅尔·米格尔

1
(a=()=>alert(($ {a})))()
丹尼斯·C

19

GolfScript,8个字节

我一直以为最短的(true)GolfScript quine是9个字节:

{'.~'}.~

在需要尾随换行的地方,因为默认情况下,GolfScript将打印尾随换行。

但是我刚刚发现了一个8字节的quine,它可以完全解决换行限制:

":n`":n`

在线尝试!

因此要注意的是,GolfScript不打印尾随换行符,而是n在程序末尾打印的内容。只是其中n包含换行开始。因此,我们的想法是将其替换为字符串":n`",然后对其进行字符串化,以使堆栈上的副本使用引号打印,而副本中存储的副本n不带引号。

正如Thomas Kwa指出的那样,7字节的CJam quine也可以适用于8字节的解决方案:

".p"
.p

同样,我们需要尾随换行符。


6
Golfscript很奇怪。
CalculatorFeline

19

迷宫124个 110 53字节

感谢Sp3000打9个字节,这让我又打了7个字节。

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

在线尝试!

说明

迷宫101:

  • 迷宫是一种基于堆栈的2D语言。堆栈是无底的,并填充有零,因此从空堆栈弹出不会出错。
  • 从第一个有效字符(此处为左上角)开始执行。在每个结点,有两条或更多条可能的指令指针(IP)可以采用的路径,将检查堆栈的顶部以确定下一步要走的地方。负向左转,零向前进,正向右转。
  • 源代码中的数字不会压入相应的数字,而是弹出堆栈顶部并压入n*10 + <digit>。这使得容易建立大量。要开始新号码,请使用_,按0。
  • " 没有人。

首先,我将解释一个稍微简单一点的版本,该版本更长了一个字节,但魔术性却有所降低:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

在线尝试!

主要思想是使用较大的基数将源主体编码为一个数字。然后,在解码该数字以打印其余的源代码之前,可以轻松地将该数字本身打印回去。解码只是对的重复应用divmod base,在其中打印mod和继续使用div直到其为零。

通过避免{},我们需要的最高字符代码为_(95),这样基数96就足够了(通过将基数保持为低,开头的数字更短)。所以我们要编码的是:

!
"
:_96
/6 %
@9_.

将这些字符转换为它们的代码点,并将结果作为96的底数(最低有效位对应于!,最高有效位对应于.,因为这是我们分解数字的顺序),我们得到

234785020242697299628949734639258593

现在,代码以一个很酷的技巧开始(如果我可以这么说的话),它使我们能够打印回编码并保留另一个副本以进行解码,而开销却很小:我们将数字反过来放入代码中。我使用此CJam脚本计算了结果因此让我们继续进行实际的代码。从这里开始:

395852936437949826992796242020587432!
"

IP从左上角开始,向东。当它运行在这些数字上时,它只是在堆栈顶部建立该数字。数字本身完全没有意义,因为它与我们想要的相反。IP击中时!,将从堆栈中弹出此数字并进行打印。这就是在输出中再现编码的全部内容。

但是现在IP已经陷入僵局。这意味着它会转身并现在向西移动(无需!再次执行)。这次,IP方便地从后到前读取该数字,因此现在该数字位于堆栈顶部编码源的剩余部分。

当IP现在再次到达左上角时,这并不是死路,因为IP可以向左转,所以它可以向左移动,然后向南移动。这"是一个空操作,在这里我们需要将数字与代码的主循环分开。说到:

...
"
:_96
/6 %
@9_.

只要堆栈的顶部还不为零,IP就会在以下循环中遍历此相当密集的代码:

"
>>>v
^< v
 ^<<

或线性布置:

:_96%._96/

之所以采取这些措施,是因为迷宫的控制流语义。当前单元至少有三个邻居时,IP将在负堆栈值上向左转,在零处继续,然后在正堆栈值上向右转。如果由于有墙而无法选择方向,则IP会采用相反的方向(这就是为什么在代码中有两个左转的原因,尽管堆栈的顶部永远不会为负)。

循环代码本身实际上非常简单(将其压缩为Sp3000的主要贡献不是):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

一旦N达到零,控制流就会改变。现在,IP希望在/(即西边)之后直行,但那里有一堵墙。因此,如果转弯(向东),请6再次执行。这使堆栈的顶部为正,因此IP向右转(向南)并执行9。现在69,堆栈的顶部是,但是我们所关心的只是它是积极的。IP向右转(向西),然后移到,@以终止代码。

总而言之,实际上很简单。

好的,现在我们如何删除该额外的字节。显然,无操作看起来很浪费,但是我们需要另外一行:如果循环与数字相邻,则IP已经可以立即移动到那里而不是遍历整个数字。因此,我们可以对无操作执行一些有用的操作。

好吧,原则上我们可以使用它来将最后一位数字添加到编码中。编码并不需要全部都在第一行上…… !只需确保那里也打印任何内容

不过有一个陷阱,我们不能仅仅这样做:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

问题是,现在我们已经改变了"3,这也改变了我们想拥有的实际数量。可以肯定的是这个数字不会以结尾3。由于数字完全由代码开始确定,因此!我们对此无能为力。

但是也许我们可以选择另一个数字?3只要最终得到一个正确编码源的数字,我们就不会在乎该点是否存在。好吧,不幸的是,这10位数字都不产生一种编码,其最低有效位与所选数字相匹配。幸运的是,代码的其余部分还有一些余地,这样我们就可以尝试更多的编码而又不增加字节数。我发现了三个选择:

  1. 我们可以更改@/。在那种情况下,我们可以使用中的任何数字1357并获得匹配的编码。但是,这意味着程序随后将以错误终止,这是允许的,但看起来不是很干净。
  2. 空格不是唯一的“墙”字符。每个未使用的字符,尤其是所有字母。如果我们使用大写字母,那么甚至不需要增加基数来容纳它(因为这些代码点在下方_)。26种选择提供了很多可能性。例如,对于A任何奇数位作品。这样会更好一些,但看起来似乎还不够优雅,因为您永远不会在真实代码中使用字母。
  3. 我们可以使用更大的基础。只要我们不显着增加基数,编码中的小数位数将保持不变(具体来说,最大为104的任何基数都可以,尽管基数超过99的情况下,代码本身实际上需要其他字符)。幸运的是,base 98提供了一个匹配的解决方案:当我们使用数字时1,编码也以结尾1。这是96、97、98、99基数中的唯一解决方案,因此确实非常幸运。这就是我们最终得到此答案顶部代码的方式。

19

失落293个 262 249字节

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

在线尝试!

说明

整个项目经历了波折。我一直认为这是不可能的,然后提出了一个可行的疯狂想法。

为什么《迷Qu》如此难?

如您所知,Lost是一种2D编程语言,其起始位置和方向完全是随机的。这使得编写任何丢失的程序几乎与编写经过辐射增强的代码一样困难。您必须考虑所有可能的位置和方向。

话虽这么说,但是有一些标准的做事方法。例如,这是打印字符串的标准方法。

>%?"Stringv"(@
^<<<<<<<<<<<<<

它的底部有一个收集流,可收集大多数ip并将其拉到起始位置。一旦它们到达起始位置(左上),我们将通过循环处理它们,以清除堆栈上的所有值,然后安全地推入字符串并退出。(安全性是“丢失”所特有的概念,每个程序%在退出前必须先命中一个,这可以防止程序在启动时终止)。现在,我的想法是将这种形式扩展为完整的quine。

首先要做的是稍微修改循环,现有循环特定于String格式。

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

我们需要添加第二个流,以避免!跳过该流并创建循环的可能性。

现在,我们要将其与标准Quine格式混合使用。由于丢失的是基于非常克莱恩我已经基本上被盗借用克莱恩奎因的马丁·安德

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

这非常方便地打印了藜的第一行。现在,我们要做的就是对流进行硬编码。好吧,这说起来容易做起来难。我尝试了大约四种不同的方法来执行此操作。我只描述一个可行的方法。

这里的想法是使用门来获得所需数量的箭头。门是一种特殊类型的镜子,每次被撞时都会改变。 [反映了来自左侧和]右侧的ip 。当它们从任一侧被ip击中时,开关方向。我们可以将这些门和一个静态反射器排成一行,以重复执行操作。

>:[[[

将执行:三遍。这样,如果我们<事先将a压入堆栈,我们可以用更少的字节制作很多。我们将其中的2行制作成一行,然后在每行之间放一个换行符,但是第二行只需要等到覆盖!我们添加的行之后,其他任何内容都可以留空以节省我们几个字节。好的,现在我们需要将垂直箭头添加到流中。这就是进行密钥优化的地方。与其直接将所有ip重定向到程序的“开始”,我们不如将它们重定向到最左边,因为我们已经知道从最左边开始的ip 必须工作(或至少将在最终版本中工作),我们也可以仅重定向其他ip。这不仅使字节便宜,而且我认为这种优化使之成为可能。

但是,仍然存在一些问题,最重要的问题是ips在>推入后开始,但在我们开始制作它的副本之前就开始了。这样的ip会进入复印机并产生一堆0的副本。这很不好,因为我们的堆栈清除机制使用零来确定堆栈的底部,而在底部则留下一整堆零。我们需要添加更强大的堆栈卫生方法。由于没有真正的方法可以判断堆栈是否为空,因此我们仅需尝试破坏堆栈中尽可能多的项目。在这里,我们将再次使用前面介绍的door方法。我们将((((((((((([[[[[[[[[[[[[[在sanitizor之后添加到第一行的末尾以消除零。

现在又有一个问题,因为我们将流重定向到从处开始的左上ip,%而向下移动将已经关闭安全性并过早退出。因此,我们需要关闭安全性。我们通过#在流中添加a 来做到这一点,这样流经该流的ip将被关闭,但已经被清理的ip不会被关闭。该#还必须硬编码到第一线为好。

就是这样,希望您现在能理解它是如何工作的。


:/如此多的错别字和链接丢失
仅ASCII码,

17

是的1165 879 606 561 540 522 498 + 7 = 505字节

需要-cheat标志以允许定义别名。

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

在线尝试!

说明

这有两个部分(与大多数奎因一样)。数据:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

和解码器:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

数据仅仅是解码器的二进制编码(或者相反)。每个0开始一个新字符,并且1s和2s分别是0-和- 1位。

请注意,这0是一个标准的Yup命令,该命令将零推入,而此时12未定义。但是,我们将整个数据部分分配给命令,%以便12可以保持未定义状态,直到%实际使用为止。

接下来,我们定义更多命令:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<递减堆栈的顶部,>递增它。1(有点不直观)将栈顶加倍。2将其加倍,然后递增。由于这些定义,类似的东西0221111实际上会在堆栈上留下48(二进制的110000)。

其余的32个字节分为两部分进行实际解码。首先,我们需要重建数据字符串。

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

最后,我们再次推送数据并将每个值打印为字符:

%{@}

为了将来参考,下面是一个CJam脚本来对数据进行编码。


17

Fueue,423个字节

Fueue是基于队列的esolang,其中正在运行的程序队列。

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

在线尝试!

这个怎么运作

这种解释可能会或可能不会失控。另一方面,我不知道如何以希望人们能效仿的方式将其解释得更短。

适当的备忘单

有关详细信息,请参阅esolang Wiki文章,包括该程序未使用的一些功能。

  • 初始程序是队列的初始状态,可以包含以下元素:

    • 整数文字(在源中只能是非负数,但可以计算出负数),执行它们会打印一个字符。
    • 方括号定界的嵌套块是惰性的(除非某些功能对其起作用,否则保持完整)。
    • 函数,其参数是队列中紧随其后的元素:
      • +*/-%:整数算术(-一元,%逻辑取反)。如果没有给定数字参数,则为惰性。
      • ()<:将元素放在方括号中,从块中除去括号,将最终元素添加到块中。除非后面有空格,否则后两者是惰性的。
      • ~::交换,重复。
      • $:复制(带数字+元素)。在非数字之前为惰性。
      • H:停止程序。

    请注意,虽然[]嵌套,()但不要-后者只是单独的函数。

执行跟踪语法

除数字之间的空格外,Fueue中的空格是可选的。在以下执行跟踪中,它将特别用于建议程序结构:

  • 当一个函数执行时,它及其参数将与周围的元素之间留有空格。如果某些参数很复杂,它们之间也可能存在空格。
  • 许多执行轨迹在左侧分为一个“延迟斑点”,从右侧的一部分分离出来,进行大量的数据处理。请参阅下一节。

{}轨迹中使用花括号(Fueue中未使用)来表示数学表达式的整数结果。这包括负数,因为Fueue只有非负文字,这-是负函数。

各种元变量名称,...用于表示值和缩写。

拖延战术

直观地,执行周期围绕队列进行,部分修改了它所经过的内容。在下一个循环之前,无法再次作用函数的结果。程序的不同部分只要不交互,就可以有效地并行发展。

结果,许多代码专用于同步,特别是将程序的某些部分的执行延迟到正确的时间。打高尔夫球有很多选择,这往往会使这些部分变成不可读的斑点,这些斑点只能通过逐周期跟踪其执行过程来理解。

这些策略在下面不会总是被单独提及:

  • )[A]延迟A一个周期。(可能是最简单,最易读的方法。)
  • ~ef交换元素ef这也会延迟其执行。(可能是可读性最差的,但对于最短的延迟通常最短。)
  • $1e延迟单个元素e
  • -并且%对于延迟数字很有用(后者用于01。)
  • 连续延迟几个相等的元素时,:$可用于从单个元素创建它们。
  • (n包裹n在括号中,这可在以后方便移除。这对于数字计算尤为重要,因为数字太不稳定,以至于即使不先将它们放在块中也无法复制。

整体结构

其余的解释分为七个部分,每个部分用于运行程序的一部分。大部分重复之后的较大循环将被称为“迭代”,以将其与遍历整个队列的单次通过的“循环”区分开。

以下是初始程序在它们之间的分配方式:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

程序末尾的大数字将其余字符反向编码,每个字符两位,从每个ASCII值中减去30(例如,10(。进行编码)。

在更高的层次上,您可以认为该程序中的数据(从bignum开始)从右向左流动,但控制从左向右流动。但是,在较低级别上,Fueue始终使代码和数据之间的区别变得混乱。

  • G节将bignum解码为ASCII数字(例如,数字0作为整数48),首先分割最低有效数字。每15个周期产生一位数字。
  • F节包含产生的数字ASCII值(每个在一个块内),直到E节可以使用它们为止。
  • E节一次处理两个产生的数字,将它们配对成表格的块[x[y]],并打印每对的编码字符。
  • D部分由一个嵌套的深度嵌套的块组成,这些[x[y]]块由这些块逐步构建而成,这样,一旦包含所有数字,就可以运行以打印所有数字,然后暂停整个程序。
  • C节处理D节的构造,并重新创建E节。
  • B节每隔30个周期重新创建C节及其自身。
  • A部分递减计数,直到其他部分的最后一次迭代。然后中止B节并运行D节。

A节

A节负责安排程序的结束时间。减少到一个交换函数~,需要4258个周期,然后对B部分进行调整,使其停止其主循环并开始运行D部分。

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • 一个$函数创建以下内容的4255个副本,%(~括号括起来。
  • 每个循环%都用完最后一个循环,以在0和之间切换以下数字1
  • 当所有%s用完时,将$1创建1个[~](实际上是NOP)副本,然后在下一个循环中)删除括号。

B区

B节每隔30个周期处理自身的更新以及C节的新迭代。

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • :复制的大块以下(一个拷贝简称为[BkB]),然后)去除第一复制括号。
  • $$24%%0 设置与A部分类似的倒计时。
  • 在递减计数的同时,:<将变为<<,并~交换两个块,最后将代码放置在新节C中。
  • 这两个<函数将两个最后的块打包为第一个块-在正常的迭代中这是多余的,但将允许~from节最后执行其工作。
  • (1)倒计时结束后,)取下外支架。接下来~:)变成C ):并将其~)交换)到C节代码的开头。
  • (2)B节现在又回到了初始周期,而a )刚要去掉方括号,开始运行C节的新迭代。

在最后的迭代中,~A部分的起始位置出现在上方的(1)点:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

~掉期)跨越块并进入部分C,防止B节被再次运行。

C区

C节负责将新的数字字符对合并到D节的块中,并创建E节的新迭代。

下面显示了一个典型的迭代过程,其中包含xy代表数字的ASCII码。在第一个迭代中,传入的“ D”和“ E”元素是初始元素[H]-而不是因为先前的E部分都没有运行以产生任何数字字符对。

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • 这使用了我为此答案发现的另一种同步方法。当您~连续有多个交换函数时,该行将在每个周期缩小到大约2/3(因为一个~交换将在后面交换两个),但是偶尔会有~s 的剩余部分会严重破坏仔细地操作后续操作。
  • $11~产生这样的行。下一个在下~一个<块之间交换a 。另一个<在末尾将新的数字对块(数字x和y为ASCII码)附加到D部分中。
  • 在下一个循环中,该~行具有~~余数,该余数将a ~替换为以下内容)。另一个<将D节附加到[)))~]块中。
  • 接下来,被交换的~自身在D区中用新的E区代码交换下一个区。然后,一个新的剩余~交换一个)跨越,终于最后~~~一排掉其中的一个跨越到E节就像)已删除的括号内。

在最后一次迭代中,A 部分将B部分~换成了)C部分,但是C部分的寿命很短,以至于它已经消失了,)结束于D部分的开头。

D区

D节处理打印最终的大数字并暂停程序。在大多数程序运行过程中,B–G节将在构建过程中进行惰性干预。

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • 在程序的第一个循环中,a (将暂停功能包装H在方括号中。甲-如下,将被用作对于第一次迭代,而不是数字对一个虚设元件。
  • 包含的第一个实数对是[49[49]],对应11于数字中的最后一个。
  • 最后一个数字对[49[48]](对应于10数字的开头)实际上并未合并到该块中,但这并没有区别,因为)[A[B]])[A][B]等价,都变成了A[B]

在最后一次迭代之后,)从B部分向右交换的数据到达,D部分的块被解块。将)))~在每个子块的开头可以确保所有部件都按照正确的顺序执行。最后,最里面的块包含一个H暂停程序。

E节

E部分处理由G部分产生的ASCII数字对的组合,并且都打印相应的编码字符,并向组合C和D向左发送一个带有组合对的块。

再次,下面显示了一个典型的迭代过程,该迭代过程用xy代表了数字的ASCII码。

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • 交换输入的数字块,然后将y块附加到x块,然后复制整个对块。C和D部分将保留一份副本,直到最后。
  • 另一个副本再次被解块,然后应用一系列算术函数来计算10*x+y-498编码字符的ASCII值。498 = 10*48+48-30中,48小号撤消的ASCII编码xy同时30从偏移编码00–9930–129,其中包括所有可打印的ASCII。
  • 然后,生成的数字将继续执行,并打印其字符。

F节

F节由包含数字ASCII码的惰性块组成。对于大多数运行的程序,此处最多会有两个,因为E节以与G生成它们的速度相同的速度消耗它们。但是,在最后的打印阶段,一些多余的0数字将在此处收集。

[y] [x] ...

G节

G节负责在程序结尾处拆分大数字,首先是最低有效数字,然后将其ASCII码向左发送的块发送到其他节。

由于它没有暂停检查功能,因此0当数字减少到0时,它将实际上继续产生数字,直到D节暂停具有该H功能的整个程序。

[BkG] 缩写大起始代码块的副本,该副本用于自我复制以开始新的迭代。

在第一个周期中初始化:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

典型的迭代,N表示要拆分的数字:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • 这里的延迟斑点特别多毛。但是,唯一的新延迟技巧是使用+:5而不是--10延迟10两个周期。las,程序中只有10s个受此帮助。
  • [N][BkG]块复制,然后的一个副本N除以10
  • [{N/10}]被复制,然后使用更多的算术函数来计算Nas 的最后一位的ASCII码48+((-10)*(N/10)+N)。带有此ASCII代码的块保留在F节中。
  • [{N/10}]获取的另一个副本在[BkG]块之间交换,以设置新迭代的开始。

奖励奎因(540字节)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

在线尝试!

由于我不确定哪种方法最短,因此我首先尝试将字符编码为以(s 分隔的两位数字。核心代码要短一些,但是数据表示要大50%才能弥补。不像其他人那样打高尔夫球,当我意识到它不会打败我时就停下来了。它具有一个优点:不需要具有bignum支持的实现。

它的整体结构与主要结构类似。由于数据表示直接填写F部分,因此缺少G部分。但是,E节必须执行类似的divmod计算,以重构两位数字的数字。


1
您应该了解一下XD
VFDan

1
)$n[)](是延迟计数器短一个字节。
jimmy23013

15

果冻,3个字节

”ṘṘ

在线尝试!

验证

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

这个怎么运作

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ

请使用哪个版本的解释器?当我对其进行测试时,即使输入位于Jelly的代码页中,它也会以UTF-8格式输出(并且编码的更改将使它不是一字形)。

1
输出的编码取决于终端的设置:如果将其设置为UTF-x,它将使用该编码;如果设置为其他任何值,则使用Jelly的代码页。在Linux上,LANG=en_US仅此而已。tio.run/nexus/bash#@@/...
丹尼斯
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.