home : articles : Oscillating (Iterating) Quine with Initial Transient
A quine is a self-replicating program. A program that, when run, prints itself. Below is a quine-like program in C language that does something a little different than a standard self-replicating program. It prints another program that, when compiled, prints another program, and keeps going for 26 iterations after which it loops back and starts printing the 13th iteration through 26th iterations over and over. I call it an oscillating quine with initial transient.
/* Comments and linebreaks included for cleaner display. Remove them for pure quineness. */ /* 2010-05-20: Verified using gcc version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5657) */ /* 2022-08-09: Needs flag -Wno-implicit-function-declaration to compile with Apple "gcc", which is actually Apple clang version 13.1.6 (clang-1316.0.21.2.5) */ int main() { int n=((-12%13)+1); char*A="int main(){ int n=((%d%c13)+1); char*%c=%c%s%c;printf(%c,n,37,76+n,34,%c,34,76+n,76+n,10);}%c"; printf(A,n,37,76+n,34,A,34,76+n,76+n,10); }
Quines
To repeat, a quine is a self-replicating program; a program that prints itself when run. I was reading an article about recursion in zip files and the article encouraged readers to stop reading, go create their own quine, and then come back. So I did. I wrote mine in C. It wasn't as pretty as the ones I found after it, but it wasn't too shabby. Here is the quine in C that I liked the best, listed in its pure form with no linebreaks.
int main(){char*s="int main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}
(As an aside, I'm being excessively picky with my quines in that they must include the newline at the end of the file, so that using the diff command results in an exact match.) But I really wanted to build something a bit different than what's been done before, so...
Iterating Quines
I thought of making an iterating quine. A quine that produces a program that, when compiled and run, prints the original program. Basically, program A produces program B and program B produces program A. This too, has already been done. These are called iterating quines.
/* An iterating quine. */ /* Remove comments and newlines or just run it for a couple of iterations. */ int main(){ int n=98; char*a="int main(){int n=%d;char*%c=%c%s%c;printf(%c,n==97?n+1:n-1,n,34,%c,34,n,n,10);}%c"; printf(a,n==97?n+1:n-1,n,34,a,34,n,n,10);}
Or, Put in Another Way, Oscillating Quines
So let's take it further. We can extend the idea of iterating quines that ping pong back and forth to a larger number of steps before returning to the original program. Being an electrical engineer, I like to think of these quines as oscillating with a certain period of oscillation. The simplest iterating quine has a oscillation period of 1. It hops back and forth every iteration. I wanted to a create quines that oscillates with a period of 3 or even more, e.g., program A produces program B produces program C, which finally produces program A. Again, these have been done before; but, in the midst of creating a quine to do this, I accidentally stumbled on something slightly different, which is possibly new. It's at least new in the sense that a few quick Google searches didn't turn up any obvious examples.
Startup Transient
I created a quine that goes through of series of programs and loops back part of way. In other words, program A produces program B produces program C, which then produces program B. It loops back and iterates, but loops back only part of the way, not all the way back to where it started. Again, given my electrical engineering bent, I refer to program A as a startup transient analogous to transients in linear time-invariant circuits. I could just start with program B and skip program A altogether. So program A is kind of unnecessary, but it is interesting that you start with program A and still end up with a quine even though program A is never repeated. The quine I finally implemented extends the startup transient to 13 steps extends the period of oscillation to 13 steps. So the first 13 steps occur only once and the next 13 repeat forever.
Show Me Don't Tell Me
Here's a little shell script that will help to demonstrate the startup transient and period of oscillation of the first quine I listed above. On a Unix system, run the following shell script. It creates the seed file 0.c and iterates 37 times, showing the output. You'll need to have gcc installed for it work.#!/bin/sh # Create first quine in quine0.c echo 'int main(){int n=((-12%13)+1);\c' > quine0.c echo 'char*A="int main(){int n=((%d%c13)+1);char*%c=%c%s%c;\c' >> quine0.c echo 'printf(%c,n,37,76+n,34,%c,34,76+n,76+n,10);}%c";\c' >> quine0.c echo 'printf(A,n,37,76+n,34,A,34,76+n,76+n,10);}' >> quine0.c cat quine0.c # Loop starting with quine0 to generate each subsequent quine. for i in {0..37} do j=$[$i+1] gcc -Wno-implicit-function-declaration "quine$i.c" -o "quine$i" &> /dev/null "./quine$i" > "quine$j.c" cat "quine$j.c" done
So How Does It Work?
Quines are fun little oddities, and you would be deprived of the fun if I were to explain in detail how they work. It's best to find out for yourself.
(Article first posted 20 March 2010. Updated 9 August 2022.)