脆弱的奎因


30

脆弱的奎因

脆弱的quine是满足通过删除单个字符来组成每个子字符串的属性的quine,在评估时会产生错误。

例如。如果您的程序asdf是木盒,那么它就很脆弱,以下程序必须出错:

sdf
adf
asf
asd

您的程序(及其所有子字符串)必须是完全确定性的,并且必须使用相同的语言。就此挑战而言,即使最终未产生错误,陷入无限循环(即无法终止)的程序也被视为“产生错误”。

存在标准漏洞,包括通常的quine限制(例如,无法读取自己的源代码)。

例如,print("foo")不是脆弱的。所有这些子字符串必须出错:

rint("foo")
pint("foo")
prnt("foo")
prit("foo")
prin("foo")
print"foo")
print(foo")
print("oo")
print("fo")
print("fo")
print("foo)
print("foo"

不会出错的是:

print("oo")
print("fo")
print("fo")

因此它并不脆弱。

关于藜的重要说明

通过协商一致,任何可能的奎纳必须满足以下条件:

必须有可能识别程序的一部分,该部分对程序的不同部分进行编码。(“不同”表示两个部分出现在不同的位置。)

此外,木盒不得直接或间接访问其自身的源。

由于我认为JavaScript的function#toString是“正在读取其自身的源代码”,因此我不允许这样做。但是,如果我不想禁止它,那么这是JavaScript中的一个脆弱的方法:

f=(n=b=`f=${f}`)=>(a=(n)==`f=${f}`,n=0,a)&(n!=b)?b:q

测试仪

这是一个程序,在给定程序源代码的情况下,它会生成所有必须出错的程序。

let f = (s) =>
  [...Array(s.length).keys()].map(i =>
    s.slice(0, i) + s.slice(i + 1)).join("\n");

let update = () => {
  output.innerHTML = "";
  output.appendChild(document.createTextNode(f(input.value)));
};

input.addEventListener("change", update);

update();
#output {
  white-space: pre;
}

#input, #output {
  font-family: Consolas, monospace;
}
<input id="input" value="print('foo')">
<div id="output"></div>


我可以使用HQ9 +吗?
奥利弗·尼

1
@OliverNi No
Conor O'Brien

3
这是对语言功能的假设 -并非所有语言都有“错误”。
Mego

2
也可以使用@Mego无限循环代替错误。每种图灵完备的语言都有无限循环。
feersum

1
@Mego无关紧要。如果每个问题仅适用一个有限子集,为什么还要烦恼提出一般情况呢?
Conor O'Brien

Answers:


6

滑稽32 28 25字节

{3SHWD{Je!}.+{Sh}\msh}Je!

在这里尝试。

因此,滑稽表演中的大多数指令都是2个字符。而且在Burlesque中写一个quine比在Marbelous中写容易得多。Je!^^e!装置_~中CJam。


1
等一下...如果这不是打高尔夫球的(到目前为止是最短的),那么我无法想象打高尔夫球是什么!+1
丹尼尔(Daniel)

@Dopapp问题在于Burlesque有太多指令,所以很可能我错过了一些东西。
jimmy23013'9

11

Python 3,45个字节

c='print(end="c=%r;exec(c"%c+c[8*4])';exec(c)

切换到Python 3,以便可以轻松删除尾随的换行符。

我从一个笨拙的结构开始,该结构具有2个变量而不是1个变量,但是切换到1个变量只会使其短4个字节。

-(4 + 3)个字节,由Dennis提供。


不知道断言。做得好
破坏的柠檬

2
如果您添加解释,那就太好了。
萨尔赫·博尔希

将您的exec结构与我的%技巧结合在一起,共有c='print(end=len(c)%5*"c=%r;exec(c)"%c)';exec(c)48个字节。
丹尼斯

1
c='print(end="c=%r;exec(c"%c+c[8*4])';exec(c)再节省3个字节。
丹尼斯

7

Python,91/92 67字节

真有趣!

现在我知道断言:

s='s=%r;assert len(s)==34;print(s%%s)';assert len(s)==34;print(s%s)

如果从字符串中删除了一个字符,则声明错误。断言,如果我知道这个功能,我会早做的。


2
我忘记了尾随换行符的问题...如果您算上它,那么我们的答案是无效的,因为可以安全地删除它。
feersum

7

Python 2,51 50 46字节

lambda s='lambda s=%r:s[22:]%%s%%s':s[22:]%s%s

Ideone上进行验证


确实允许使用功能喹。
科纳·奥布莱恩

1
??我从未听说过允许将函数用作quines ...对此有任何示例吗?
feersum'9

@feersum查询javascript quine会产生一些结果。
丹尼斯

@feersum标准Mathematica quine也基于函数(使用#0)。
马丁·恩德

2
我只是换了个样子,大多数 JS或Mathematica quines实际上也调用了该函数。因此,将它们称为REPL quines更正确。也就是说,Conor在此挑战说明中提供的示例只是一个函数,因此我想至少在这里是有效的。
Martin Ender

4

C#,145个字节

_=>{var@s="_=>{{var@s={1}{0}{1};for(;79!=s.Length;){{}}System.Console.Write(s,s,'{1}');}};";for(;79!=s.Length;){}System.Console.Write(s,s,'"');};

我以前没有用C#编写过奎因,但是高尔夫得分越高越好,对吧?:)

如果从字符串中删除了字符或从魔术常量79中删除了一个字符,则发生无限循环。删除任何其他字符会导致编译错误。

取消高尔夫:

/* Action<object> Quine = */ _ => // unused parameter
{
    // String of the function (well, mostly).
    // {0} placeholder for s, so the output contains the function and string.
    // {1} placeholder for " since it requires escaping.
    var@s = "_=>{{var@s={1}{0}{1};for(;79!=s.Length;){{}}System.Console.Write(s,s,'{1}');}};";

    // Infinite loop if a char is removed from the above string or if the 7 or 9 is removed.
    for(;79!=s.Length;){}

    // Print the quine.
    System.Console.Write(s,s,'"');
};

3

JavaScript,90个字节

a="a=%s;a[44]!=')'?x:console.log(a,uneval(''+a))";a[44]!=')'?x:console.log(a,uneval(''+a))

在Firefox 48的控制台,以及任何其他环境应该工作unevalconsole.log。错误分类:

a="                                             "; [  ]!=' '?x:           (a       (''+a))   // SyntaxError
   a=%s;a[44]!=')'?x:console.log(a,uneval(''+a))  a 44    )                                  // ReferenceError from calling `x`
                                                               console.     ,uneval          // ReferenceError from calling `onsole.log`, `auneval`, etc.
                                                                       log                   // TypeError from calling `console.og`, etc.

哇,不知道不安 另外,很高兴看到您至少回来了!:D
Conor O'Brien

@ ConorO'Brien很高兴(至少有点)回来了!我已经发布了对夫妇 奎因-Y 答案使用这种技术。
ETHproductions's

2

Python 2,59个字节

x='x=%r;1/(len(x)==30);print x%%x';1/(len(x)==30);print x%x

ZeroDivisionError如果从字符串中删除了0、3或一个字符,则会抛出a 。删除其他字符将导致NameErrorSyntaxError


2

梨树,50字节

a="print('a='.repr(a).';eval(a)');#f+QF>";eval(a)

在线尝试!

不是最短的答案,而是相当全面的答案;从此程序中删除任何字符都会导致其校验和失败,因此A Pear Tree解释器甚至不会尝试运行它。(例如,如果删除结尾的换行符,则会出错。);#f+QF>使用来确保整个程序的CRC-32为0(并且f+QF>是可以放置在三个可能的5字节字符串中的一个)。注释以在保持ASCII的同时实现该目标;在此使用ASCII很重要,因为repr否则将无法正确地将其往返。

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.