><>, 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.
Does this count?
0
and00
in CJam both output0
. – geokavel – 2017-07-15T04:11:22.487No,
0
is not a proper quine. – Dennis – 2017-07-15T04:18:46.3402I 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