A Fragile Quine

30

2

A Fragile Quine

A fragile quine is a quine that satisfies the property of having each substring made by removing a single character, when evaluated, produces an error.

For example. If your program asdf is a quine, then for it to be fragile, the following programs must error:

sdf
adf
asf
asd

Your program (and all of its substrings) must be fully deterministic, and must be in the same language. A program falling into an infinite loop (that is, failing to terminate), even if not eventually producing an error is considered to "produce an error" for the purposes of this challenge.

Standard loopholes apply, including the usual quine restrictions (e.g. not able to read own source code).

For example, print("foo") is not fragile. All these substrings must error:

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

The ones that don't error are:

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

So it is not fragile.

An important note on quines

By consensus, any possible quine must satisfy this:

It must be possible to identify a section of the program which encodes a different part of the program. ("Different" meaning that the two parts appear in different positions.)

Furthermore, a quine must not access its own source, directly or indirectly.

Example

Since I consider JavaScript's function#toString to be "reading it's own source code", I am disallowing it. However, if I weren't to bar it, here is a fragile quine in JavaScript:

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

Tester

Here is a program that, given the source code of your program, generates all programs that must error.

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>

Conor O'Brien

Posted 2016-09-05T23:48:01.847

Reputation: 36 228

Am I allowed HQ9+? – Oliver Ni – 2016-09-06T00:34:53.963

1

@OliverNi No

– Conor O'Brien – 2016-09-06T00:36:05.453

Is infinite output considered a valid error? – PurkkaKoodari – 2016-09-06T06:44:08.903

Also, is it valid to print the correct output and then crash? – PurkkaKoodari – 2016-09-06T06:53:58.483

3

This is making assumptions about language features - not all languages have "errors".

– Mego – 2016-09-06T07:31:24.307

+1 for disallowing Function.prototype.toString. – Neil – 2016-09-06T08:35:59.170

@Mego Most languages have errors. I am not terribly worried about making this possible in all languages. – Conor O'Brien – 2016-09-06T11:07:51.257

@Pietu1998 infinite output implies infinite looping, so yes; if it crashes, then that constitutes an error. – Conor O'Brien – 2016-09-06T11:09:41.820

2@Mego Infinite loops are also allowed instead of errors. Every Turing-complete language has infinite loops. – feersum – 2016-09-06T12:19:35.673

@feersum Not true. Lambda calculus has recursion, not loops. It's not clear whether or not infinite recursion would count as an infinite loop. – Mego – 2016-09-06T17:35:22.473

@Mego how about running infinitely -.- – Conor O'Brien – 2016-09-06T19:38:27.670

@ConorO'Brien I have a million dollars for you if you can prove that an arbitrary program doesn't terminate. – Mego – 2016-09-06T19:48:29.580

1@Mego that is irrelevant. Why even bother bringing up the general case if only a finite subset applies per problem? – Conor O'Brien – 2016-09-06T20:07:55.617

Answers

6

Burlesque, 32 28 25 bytes

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

Try it here.

So most instructions in Burlesque are 2 characters. And it is much easier to write a quine in Burlesque than in Marbelous. Je! or ^^e! means _~ in CJam.

jimmy23013

Posted 2016-09-05T23:48:01.847

Reputation: 34 042

1Wait...if this is not golfed (and is by far the shortest here), then I can't imagine what golfed is! +1 – Daniel – 2016-09-06T23:31:27.920

@Dopapp The problem is Burlesque has too many instructions, so it is very likely I missed something. – jimmy23013 – 2016-09-06T23:33:55.427

11

Python 3, 45 bytes

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

Switching to Python 3 so that the trailing newline can be easily removed.

I started out with a stupid structure that had 2 variables instead of 1, but switching to 1 variable only made it 4 bytes shorter.

-(4 + 3) bytes by Dennis.

feersum

Posted 2016-09-05T23:48:01.847

Reputation: 29 566

didn't know about assert. Good work – Destructible Lemon – 2016-09-06T02:49:19.680

2Would be great if you add an explanation. – Display Name – 2016-09-06T05:23:01.557

Combining your exec structure with my % trick, there's c='print(end=len(c)%5*"c=%r;exec(c)"%c)';exec(c) for 48 bytes. – Dennis – 2016-09-06T06:31:48.473

1c='print(end="c=%r;exec(c"%c+c[8*4])';exec(c) saves 3 more bytes. – Dennis – 2016-09-06T22:34:56.547

7

Python, 91/92 67 bytes

This was fun!

Now I know about assert:

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

If a char from string is removed, assert error. I would have done this sooner had I known of this feature, assert.

Destructible Lemon

Posted 2016-09-05T23:48:01.847

Reputation: 5 908

2I forgot about the trailing newline question... if you do count it, then our answers are invalid since it can be safely removed. – feersum – 2016-09-06T02:41:19.597

7

Python 2, 51 50 46 bytes

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

Verify it on Ideone.

Dennis

Posted 2016-09-05T23:48:01.847

Reputation: 196 637

Function quines are indeed allowed. – Conor O'Brien – 2016-09-06T03:19:33.463

1Huh? I've never heard of functions being allowed as quines...are there any examples for this? – feersum – 2016-09-06T03:21:43.727

@feersum The query javascript quine yields a few results.

– Dennis – 2016-09-06T03:24:16.497

@feersum the standard Mathematica quine is also function based (using #0). – Martin Ender – 2016-09-06T05:58:29.197

2I just had another look and most JS or Mathematica quines actually also call the function. So it would be more correct to call them REPL quines. That said, the example provided by Conor in the spec of this challenge is just a function, so I guess at least it's valid here. – Martin Ender – 2016-09-06T06:35:40.763

Let us continue this discussion in chat.

– Erik the Outgolfer – 2016-09-06T18:10:54.700

4

C#, 145 bytes

_=>{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,'"');};

I've not written a quine in C# before, but higher scores are better in golf, right? :)

Infinite loop if a char is removed from the string or a digit from the magic const 79. Removing any other char results in a compile error.

Ungolfed:

/* 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,'"');
};

milk

Posted 2016-09-05T23:48:01.847

Reputation: 3 043

3

JavaScript, 90 bytes

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

Works in the console of Firefox 48, and should work in any other environment with uneval and console.log. Breakdown of errors:

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.

ETHproductions

Posted 2016-09-05T23:48:01.847

Reputation: 47 880

Wow, didn't know about uneval. Also, nice to see you at least somewhat back! :D – Conor O'Brien – 2016-09-07T01:35:00.047

@ConorO'Brien Nice to be (at least somewhat) back! I've posted a couple more quine-y answers using this technique.

– ETHproductions – 2016-09-07T01:37:04.747

2

A Pear Tree, 50 bytes

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

Try it online!

Not the shortest answer, but a fairly comprehensive one; any character deletion from this program causes it to fail to checksum, thus the A Pear Tree interpreter won't even attempt to run it. (For example, you get an error if you delete the trailing newline.) The ;#f+QF> is used to ensure that the program as a whole has a CRC-32 of 0 (and f+QF> is one of three possible 5-byte strings that could be placed in the comment to achieve that while staying in ASCII; using ASCII is important here because repr would fail to round-trip it correctly otherwise).

user62131

Posted 2016-09-05T23:48:01.847

Reputation:

2

Python 2, 59 bytes

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

This throws a ZeroDivisionError if a 0, a 3, or a character is removed from the string. Removing a different character results in a NameError or a SyntaxError.

Daniel

Posted 2016-09-05T23:48:01.847

Reputation: 6 425