Quines are programs that, when you run, will print out its own source text.

You can read this very long article about how to write one in C. Here we're going to do it in Python and skip a lot of the details and theory.

You can, of course, "just" read the data from disk:

import sys

print(open(sys.argv[0], 'r').read())

This is obviously cheating though. It only works if we call it the right way, and is dependent on the command line to work. Really we want something pure that can be done in most programming languages. Something solid.

Firstly... we want a program that prints out a result. So we'll need at least one print statement.

print()

This prints out one empty line, but establishes a first thing: we would like to print out print!

print("print()")

So this prints out print(). But now we're going from two prints down to one.

Right now we have a bit of a problem. If we add a character to the string we print, then our output gets 1 character longer, but so does our target.

We need our output to be the same as the code. So we need the length of our output to catch up to the length of the code.

It's, of course, very easy to make our output much longer than the length of the source code by doing things like:

for \_ in range(100):
  print("print()")

This will make our output much longer than the source code, though also not very close to the source code.

We want to compress our output data so that we have some chance to catch up.

We have at least two prints in the existing code, so let's start there.

p = "print"
print("%s()" % p)

(some_str % parameters is Python's equivalent to printf, where the string parameters get placed at %s)

This feels like we are going in the wrong direction! Not only have we added more characters, but now there's not even two print statements, so our compression idea is failing!

But we're actually on the right track, because we have decoupled our output length from the code length, at least a bit.

Let's first try to fix our print statement to at least print this new first statement.

As a note, "->%r" % "abc"gives "->'abc'", we are rendering Python values with repr instead of str.

p = "print"
print("p = %r\n%s()" % (p, p))

The above percentage soup gives us, in output:

p = 'print'
print()

Now we seem to still have a problem with this print statement. But where as before we were having trouble reproducing the outermost print, now our problem is about generating the innards.

If we try to write the innards of the print statement, we're going to run into an endless recursion

print("p = %r\n%s(?)" % (p, p))
print("p = %r\n%s('p = %%r\n%%s(?)')" % (p, p))

Tryin to fill in the ? with itself is getting us nowhere fast.

But notice how we don't have to write the print statement within the print statement anymore. Sure, this was a dead end, but the idea is sound. How can we avoid mentioning the template again?

Let's factor out this template string into a value called t.

p = "print"
t = "p = %r\n%s()"
print(t % (p, p))

From here, again, we want to print out this new assignment by adding t = %r

p = "print"
t = "p = %r\nt = %r\n%s()"
print(t % (p, t, p))

This gets us to the following output:

p = 'print'
t = 'p = %r\nt = %r\n%s()'
print()

We still do not have the innards of the print call!

The important thing that just happened though is that our attempts to "catch up" to the end of the code has gotten us to a point where we are no longer needing to infinitely expand our template.

We can add new text to the value of t, and that will be nicely reproduced in our end result because we are doing t % (p, t, p), i.e. injecting the template into the end result.

By typing just one character into t, we can extend our output by 2 characters!

p = "print"
t = "p = %r\nt = %r\n%s(t)"
print(t % (p, t, p))

This program outputs

p = 'print'
t = 'p = %r\nt = %r\n%s(t)'
print(t)

We have finally caught our own tail, and now are simply starting to type the innards of the (now no longer infinitely recursive) print statement.

Let's finish typing things up, and fix the quotes to match what repr does to our strings

p = 'print'
t = 'p = %r\nt = %r\n%s(t %% (p, t, p))'
print(t % (p, t, p))

The above is a quine. You run it, and the output is the same as the input. We meandered a bit but finally got there.

Here p isn't really pulling its weight, let's clean that up.

t = 't = %r\nprint(t %% t)'
print(t % t)

This is, honestly, a bit of an unexciting quine. At this point modifying the source simply involves adding the source, and updating the template.

There are no more real mysteries or challenges to reproducing the exact code itself. The magic is gone, but in its place the minimal quine can help serve as a piece of a larger puzzle.

You could make your quine change over time. The simplest example of this would be with a run count:

run_count = 0
t = 'run_count = %s\nt = %r\nprint(t %% (run_count + 1, t))'
print(t % (run_count + 1, t))

But seeing the bones of the quine too easily removes some of the magic. The point of quines is that they are unintelligable, abusing some weird mechanism.

Instead of using this code directly, you can take this core idea of injecting a template into itself, to think of ways of chaining together interesting behavior. Obfuscate in interesting ways, with weird layout. But mostly try to have fun.