21
\$\begingroup\$

Concept

Write a program that outputs code in its programming language. That code, when executed, must output the original program.

Rules

  • Since this is a cheating quine, you can read the original source code.
  • First output program must be in the same language as the original program.
  • You may not output a regular quine. The two programs must be different.
  • Standard loopholes apply.
  • This is so shortest answer wins, however it will not be selected.
\$\endgroup\$
12
  • \$\begingroup\$ I'm still not entirely sure what constitutes a semi-quine. \$\endgroup\$ Dec 11, 2016 at 23:36
  • \$\begingroup\$ @ConorO'Brien It outputs a program that outputs the original program \$\endgroup\$
    – anna328p
    Dec 11, 2016 at 23:37
  • 1
    \$\begingroup\$ I see. The wording is quite vague. \$\endgroup\$ Dec 11, 2016 at 23:40
  • 3
    \$\begingroup\$ Why wont the shortest answer be selected? Is this a Catalog? \$\endgroup\$
    – ATaco
    Dec 12, 2016 at 0:38
  • 2
    \$\begingroup\$ Just for the record, I'd call it a mutual quine (that challenge requires different languages though). \$\endgroup\$ Dec 12, 2016 at 8:02

14 Answers 14

28
\$\begingroup\$

Bash + coreutils, 11 bytes

tr xy yx<$0

This prints

tr yx xy<$0

Try it online!

In turn, that prints

tr xy yx<$0
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Not a cheat and in a common language. \$\endgroup\$
    – denson
    Dec 12, 2016 at 8:49
  • 8
    \$\begingroup\$ I think the tr command is redirected to $0 which is its own source code. So it is "cheaty". \$\endgroup\$ Dec 12, 2016 at 12:04
21
\$\begingroup\$

Snails, 0 bytes


The second program is

1

The first program counts the number of matches of the empty pattern on the empty input (which really has area 0, but the pattern is always run at least once as a hack to allow programs to decide what they want to print on empty input). The second program begins with a quantifier (like {1} in regex), which causes a parse error. Since the program does not parse successfully, STDOUT is the empty string.

\$\endgroup\$
2
  • \$\begingroup\$ I thought there was probably a language that did this (i.e. null program succeeds with a nonempty result, but that result does nothing as a program). I tried HOMESPRING but couldn't get the interpreter to work. Looks like you found another language where it works, though. (Do you have a link to an interpreter?) \$\endgroup\$
    – user62131
    Dec 12, 2016 at 23:47
  • \$\begingroup\$ @ais523 github.com/feresum/PMA or tio.run/nexus/snails​. \$\endgroup\$
    – feersum
    Dec 12, 2016 at 23:49
21
\$\begingroup\$

7, 2 bytes

7 uses a 3-bit character set, but takes input packed into bytes (and according to meta, languages with sub-byte character sets are counted using bytes for the file on disk). Here's an xxd dump of the program:

00000000: 4cf4                                     L.

When giving this file to the 7 interpreter, it will output the following program:

00000000: 4fa6 7f                                  O..

which will then in turn output the original program again.

So what's happening here? There's no source reading involved (actually, I don't think it's possible to read the source in 7), although arguably the program is cheating in another way; let me know what you think. Here's how the program works. (Note that each 7 command has two variants, some of which don't have names and can't appear in the original program. There are twelve commands total, in six pairs. I'm using bold for active commands, nonbold for passive commands, and in cases where the active command has no name, I'm giving it the same name as the corresponding passive command and relying on the bold to distinguish. In the case where both are named, e.g. 7 which is the active variant of 1, each command gets its own name and the bold is just syntax highlighting.)

231723       Original program, unpacked into octal
231          Push 237 onto the stack
    23       Push 23 onto the stack
             (implicit) append a copy of the top of stack to the program
      2      Duplicate top of stack (currently 23)
       3     Output top of stack, pop second stack element

At this point, the 7 interpreter sees that the top of stack contains commands (2 and 3) that aren't representable, so it escapes the top of the stack, producing 723 (which is). The first command output selects the output format; in this case, it's format 7, "format the output the same way as the program". So the commands get output packed into bytes. Then the program continues:

23172323
             (implicit) append a copy of the top of stack to the program
        2    Duplicate top of stack (currently 237)
         3   Output top of stack, pop second stack element
          7  Push an empty element onto the stack

At this point, there's nothing but empty stack elements on the stack, so the program exits. We output 23 earlier. If we escape 237 (and we have to, because it contains unrepresentable commands), we get 7231. That gets output directly, making the final output of the program 237231 (formatted the same way as the program, i.e. packed into bytes). That's 4fa67f. (It can be noted that the 1 was entirely pointless in terms of affecting the output; the only reason it's there is to make the two programs different.)

Running 237231 proceeds almost exactly the same way; the difference is that the useless 1 runs just after the first print (and the empty element gets implicitly deleted the second time the current end of the program is reached). Again, the 231 ends up outputting itself, the 23 ends up outputting itself preceded by a 7, and we get 231723, the original program.

The observant might note that the two programs, despite being the same length in the language's "native" octal, are different lengths on disk. That's because a 7 program can be padded with an arbitrary number of 1 bits, and the packed format discards the trailing padding. Here's how the encoding happens:

2  3  1  7  2  3
010011001111010011(1...)
4   c   f   4   padding

In other words, two bytes, 4C F4, are enough to represent the program, so that's all I used.

\$\endgroup\$
11
\$\begingroup\$

Python 3, 297 279 251 243 225 218 208 180 126 111 bytes

Non-cheating:

A=''';print(("A="+("'"*3+A)*2).translate({65:66,66:65}))''';print(("A="+("'"*3+A)*2).translate({65:66,66:65}))

This prints:

B=''';print(("B="+("'"*3+B)*2).translate({65:66,66:65}))''';print(("B="+("'"*3+B)*2).translate({65:66,66:65}))

which, when executed, prints the original program.

\$\endgroup\$
1
  • \$\begingroup\$ Wow! Cool! I never would have thought of that. \$\endgroup\$
    – anna328p
    Dec 11, 2016 at 23:43
8
\$\begingroup\$

Batch, 14 bytes

@echo @type %0

Which when run as cyclicquine.bat outputs

@type cyclicquine.bat

Which when run outputs the original batch file.

\$\endgroup\$
0
8
\$\begingroup\$

RProgN, 4 Bytes.

The community seems to consider this sort of thing as a cheating quine, which thus satisfies the criteria.

1
2

With a trailing newline.

This prints

2
1

With a trailing newline, which prints the first code.

RProgN prints the stack popping, so from top to bottom.

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ There was a chat discussion a while back which implied that 1\n1\n in RProgN would be a non-cheating quine, because each of the 1s prints each other (and it'd only be considered cheating if each 1 printed itself). All this really implies is that cheating in quines can be hard to define sometimes. (However, this answer is correct either way, because the question doesn't actually require the quine to cheat, just allows it.) \$\endgroup\$
    – user62131
    Dec 12, 2016 at 23:49
  • \$\begingroup\$ Also, Although I was reluctant to say, in RProgN 1\n is technically a valid quine, as 1 isn't a constant, but a call to a function which pushes 1 to the stack. \$\endgroup\$
    – ATaco
    Dec 13, 2016 at 0:02
  • \$\begingroup\$ There are multiple definitions of a proper quine in use. That's invalid by at least one, but possibly valid by some of the others. \$\endgroup\$
    – user62131
    Dec 13, 2016 at 0:06
  • \$\begingroup\$ @ais523 You've sparked my curiosity, You specified RProgN, yet I didn't think that my little language got that much (or any) attention. Was the chat about RProgN in particular, or a language with a similar syntax? \$\endgroup\$
    – ATaco
    Dec 13, 2016 at 4:53
  • \$\begingroup\$ It was about 7, which also has a tendency to print segments of the program "backwards". I was extrapolating from the opinions given there. \$\endgroup\$
    – user62131
    Dec 13, 2016 at 6:24
6
\$\begingroup\$

Jolf, 6 bytes

1q_a_q

When run, this outputs:

q_a_q1

Which in turn outputs 1q_a_q.

Try it here!

Explanation

1q_a_q
1       the digit one (ignored)
 q      the source code (ignored)
     q  the source code
    _   reversed
   a    and outputted
 _      and reversed (ignored)

q_a_q1
q       the source code (ignored)
     1  the digit one (ignored)
    q   the source code
   _    reversed
  a     and outputted
 _      and reversed (ignored)
\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 69 60 59 bytes

(_0=_=>console.log(`(_0=${_0})()`.replace(/0/g,n=>+!+n)))()

Outputs:

(_1=_=>console.log(`(_1=${_1})()`.replace(/1/g,n=>+!+n)))()

-1 byte (@ETHProductions): use 0 in regex instead of \d

\$\endgroup\$
3
  • \$\begingroup\$ Try n=>1-n instead of n=>+!+n. \$\endgroup\$ Dec 12, 2016 at 13:01
  • \$\begingroup\$ @Conner O'Brien Unfortunately the 1 will end up replaced by the regex. \$\endgroup\$
    – darrylyeo
    Dec 12, 2016 at 15:24
  • \$\begingroup\$ @ETHproductions Heh, I should've thought of that. \$\endgroup\$
    – darrylyeo
    Dec 12, 2016 at 20:55
3
\$\begingroup\$

Bash + Sed, 15 bytes

Same idea as Dennis's Answer.

sed y/xz/zx/ $0
\$\endgroup\$
3
\$\begingroup\$

Bash, Cat, and Rev, 19 16 bytes

rev $0 # 0$  ver

-3 thanks to @izabera

\$\endgroup\$
5
  • \$\begingroup\$ Wouldn't this be Bash, Tac, and `Rev? \$\endgroup\$ Dec 12, 2016 at 13:00
  • \$\begingroup\$ rev $0 # 0$<space><space>ver for some reason i can't put two spaces in a comment \$\endgroup\$
    – izabera
    Dec 12, 2016 at 13:09
  • \$\begingroup\$ Oh, nice @izabera \$\endgroup\$ Dec 12, 2016 at 17:07
  • \$\begingroup\$ @ConorO'Brien No, tac rev-ed is cat. \$\endgroup\$ Dec 12, 2016 at 17:07
  • \$\begingroup\$ @SeeOneRhino Oh.... I see \$\endgroup\$ Dec 12, 2016 at 18:15
1
\$\begingroup\$

><>, 16 bytes

"$r00gol?!;50.01

Try it here!

Outputs

"$r00gol?!;50.10

This is a modification of the one provided here. I'm not sure if it's cheating, it reads the codebox and outputs it.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ you can change the 00g to :2- and it'll keep the same byte count without reading the codebox. \$\endgroup\$ Dec 13, 2016 at 10:26
  • \$\begingroup\$ @Tealpelican, thanks! The goal is for it to be considered "cheating" though :p. (And I don't fully understand that rule) \$\endgroup\$ Dec 13, 2016 at 15:02
1
\$\begingroup\$

C (gcc), 55 bytes

N,s[];main(){*s^=read(open(__FILE__,0),s,54);puts(s);}

Note the trailing newline.

First run:

x,s[];main(){*s^=read(open(__FILE__,0),s,54);puts(s);}

Try it online!

Second run:

N,s[];main(){*s^=read(open(__FILE__,0),s,54);puts(s);}

Try it online!

This one is rather simple. It reads the file, and XORs the first byte (technically first int, but it is effectively the same) with 54. Since it is an unused variable, it doesn't affect anything.

Note that this abuses the empty array cheat where GCC will let you write up to one page in an array with empty brackets. It also expects the page to be zero filled, which is the default.

A version which does not write out of bounds is this:

y,s[15];main(){*s^=read(open(__FILE__,0),s,56);puts(s);}

Try it online!

Which will turn into this

A,s[15];main(){*s^=read(open(__FILE__,0),s,56);puts(s);}

Try it online!

I xor against read() because it returns the number of bytes read, and it is shorter than XORing against a constant.

\$\endgroup\$
1
\$\begingroup\$

Self-modifying Brainfuck, 22 20 bytes

Note that SMBF stores the program itself to the left of the initial pointer.

~<[<]>[-<->]<.>>[.>]

Try it online!

It will output this (replace \x82 with a 0x82 byte)

\x82<[<]>[-<->]<.>>[.>]

Which in turn will print this:

~<[<]>[-<->]<.>>[.>]

Explanation:

~      Dummy byte to be negated to 0x82 (or on second, 0x7e or ~)
<[<]   Scan backwards to the start of the program
>      Go forwards to the first byte
[-<->] Negate cell 0 into cell minus 1
<.     Print the negated byte
>>     Skip to the second byte of the program
[.>]   Print the rest of the program

Because I can't directly do it with TIO because it treats inputs as UTF-8, here is a Bash script version which prints outputs with xxd:

Try it online!

Self-modifying Brainfuck (infinite loop, theoretical), 15 bytes

This version is shorter, but instead of exiting normally, it hangs in an infinite loop. Note that you won't see this in the console as the console is line buffered.

<[.<]-[][+]<.[<

Try it online!

This will print this:

<[.<]+[][-]<.[<

which, when run, will print this

<[.<]-[][+]<.[<

Try it online!

Note that in both cases, the code will get stuck in an infinite loop after printing, so you have to manually stop TIO or wait for the timeout

Explanation:

<[.<]    Print the program backwards
-[]      Enter an infinite loop to avoid executing the backwards code
[+]<.[<  The same code backwards (minus the last bracket) which uses a minus
         instead of a plus before the infinite loop.

My previous 11 byte infinite loop solution:

<[.<]]<.[<+

Try it online!

I thought this was an infinite loop which just sat there spinning, but the instruction pointer will eventually underflow and the program will very slowly print endless 0x00 as it tries to traverse a 4 GB loop.

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 10 bytes

`:qpq`:qpq

Try it Online!

This outputs

`\`:qpq\`:qpq`

Which outputs the original code.

The first is a quine that unevaluates itself, and the second is a string.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.