Mutation-hardened quine

15

0

Your task is to make a program that prints out its own source.

"Hey, we already have this challenge, and tons of variations of it! Why are you making another one?" you may ask, but this one is going to be one of the most difficult ones (hopefully, anyway).

Your quine must be "mutation-hardened", which means the quine, even when any one of its characters are duplicated in place, must output the source code of the original program.

For example, if you have a quine (the following example is not written in any language, it's just pseudocode):

abcd

These programs must all output abcd:

aabcd
abbcd
abccd
abcdd

(In each of those programs, a, b, c and d are each duplicated in-place, which means the duplicated character was placed directly after the original character.)

Rules:

  • Standard quine rules apply.
  • A multi-byte character counts as one character, and the character is not "split" into its respective bytes when duplicated.

This is , so shortest code in bytes wins!

clismique

Posted 2017-07-15T02:09:25.990

Reputation: 6 600

Does this count? 0 and 00 in CJam both output 0. – geokavel – 2017-07-15T04:11:22.487

No, 0 is not a proper quine. – Dennis – 2017-07-15T04:18:46.340

2I think it would be much interesting as [tag:code-bowling] – Mr. Xcoder – 2017-07-15T08:51:19.783

Is the problem of code mutation solvable in general? unless the mutation happens to a character inside a quoted string, it would usually corrupt the program. – hasen – 2017-07-15T12:43:19.293

Isn't the title a bit misleading? "Mutation" suggests altering a character, not repeating it – Luis Mendo – 2017-07-15T17:50:55.717

@hasen I think this may be impossible in many languages, but after seeing this answer to a similar challenge, I'm ready to be impressed again. (Too bad that poster seems to have left.)

– Ørjan Johansen – 2017-07-15T22:57:48.537

Answers

18

><>, 56 bytes

^
.
+
8
f
0
o
a
o
~
:
?
~
:
?
:
-
*
4
8
:
^
^
}
*
3
d
'

Try it online! or verify all mutations.

How the original program works (outdated)

The interpreter starts in cell (0, 0). ^ sets the direction to upwards, so the instruction pointer (IP) wraps around to cell (0, 20).

' activates string mode: until the next ' is encountered, all characters under the IP are pushed on the stack. The same ' is found again after wrapping around, so we push

d3*}^^:84*=?~oao0f.^

The IP lands at (0, 19), still going upwards. Executing d3*} pushes 13 = 0xd, then 3, multiplies both values (39 / single quote), then rotates the stack to the right. This leaves the stack as follows.

'd3*}^^:84*=?~oao0f.^

The next two instructions (^) do nothing at this point.

:84*= duplicates the top of the stack, pushes 8 and 4, multiplies them (32 / space), then tests the duplicated character for equality with space. For the unaltered program, this will always push 0.

? skips the next instruction if the top of the stack is falsy. For the original program, it always is, so ~ is always skipped.

oao pops and prints the top of the stack, pushes a 10 / linefeed, then pops and prints linefeed.

Finally 0f. jumps to cell (0, 15) (the bottommost ^), starting over with the next character on the stack.

Once the stack is empty, the entire source code has been printed. : will fail and the program exits.

How the mutated programs work (outdated)

Duplicating any non-linefeed character will only extend the program horizontally. Since the program is executed vertically, these extra instructions will never get executed.

Duplicating any linefeed before the bottomost ^ will shift cells (0, 14) and (0, 15) to (0, 15) and (0, 16). 0f. will now jump to the cell before the bottommost ^, which is also a ^, so the program is not affected by the shift.

Finally, any duplicated linefeed character will also alter the string. Short lines are padded with spaces, so a 32 / space will be inserted at the linefeed's position. 84*= will push 1 for space, so ? doesn't skip the next instruction. In this case, ~ pops and discards space, so the following o will print the character above space instead.

Dennis

Posted 2017-07-15T02:09:25.990

Reputation: 196 637

You can duplicate any newline and it will still work. – Dennis – 2017-07-15T04:20:34.627

3Oh, I didn't read the post properly :P (Dammit Dennis, why are you so good) – clismique – 2017-07-15T04:21:32.883

4Cracked. – jimmy23013 – 2017-07-15T10:56:01.270

@jimmy23013 Should be fixed. – Dennis – 2017-07-15T17:34:05.580