Writing the Most Boring Quine
rtpg.co
rtpg.co
It was interesting to see the author work through the major obstacles one by one when writing a quine. Glad they didn't take the actual boring route!
$ ~ echo '"Hello world"' > quine.py
$ ~ cat quine.py
"Hello world"
$ ~ python quine.py
$ ~ s='s=%r;print(s%%s)';print(s%s)
Anyway, let's make it a bit less boring and make it a C/Python polyglot (not relay) quine: #include<stdio.h>
#define len int main(){char*
#define zip return 0;}
#if 0
def printf(f,*a):print(f%a,end=str())
#endif
len
s="#include<stdio.h>%c#define len int main(){char*%c#define zip return 0;}%c#if 0%cdef printf(f,*a):print(f%%a,end=str())%c#endif%clen%cs=%c%s%c;printf(s,10,10,10,10,10,10,10,34,s,34,10);zip%c";printf(s,10,10,10,10,10,10,10,34,s,34,10);zip
Same in C/Ruby: #include<stdio.h>
#define puts(c)void main(){c;putchar(10);}
#define dup char*
dup
s="#include<stdio.h>%c#define puts(c)void main(){c;putchar(10);}%c#define dup char*%cdup%cs=%c%s%c;puts(printf(s,10,10,10,10,34,s,34))";puts(printf(s,10,10,10,10,34,s,34))
Wonder if one can make that shorter.And yes, this is the most boring quine, you've punted the problem to the formatting mini-language and solved it in a manner equivalent of print(open(argv[0]).read()). I would say perhaps the ideal formulation for producing an interesting quine that doesn't leverage other languages would be "write a quine in C, using no preprocessor directives and no external functions except the POSIX write function, you may assume stdout is 1". So your program would look like:
extern long write(int, const void *, unsigned long);
int main(int, char**) {
/* your code here, using write(1, buf, count) for output */
return 0;
}
You would of course end up writing a function equivalent to 'x%x' in Python, but getting there is a bit more exciting.Did it that way so I don't need to learn about the ELF format, but use several passes to get a binary that is a quine.
I've done this up to level omega^omega at my Library of Intuitive Ordinal Notations: https://github.com/semitrivial/ions/
CODE = 'XXX'
print(CODE.replace('"XXX"', repr(CODE), 1))
Step 2: CODE = 'CODE = "XXX"\nprint(CODE.replace(\'"XXX"\', repr(CODE), 1))'
print(CODE.replace('"XXX"', repr(CODE), 1))
The beauty of this approach is that you could include the definition of the repr function in the code, so it works in any language that can manipulate strings. Another generally-applicable approach is to use eval: write a program that prints a variable assignment and an eval of that variable, then wrap that program in a variable and eval it: code = 'print("code = {!r}\\neval(code)".format(code))'
eval(code)
Again this uses "!r" for brevity but it could easily include the function responsible for doing the escaping. Requires eval, so not as universally applicable as the previous method (but produces shorter quines).Anyone aware of other generally-applicable techniques for producing quines?
#!/usr/bin/env cat
Or even shorter: #!/bin/cat (lambda s,q,b,k,c,e:print(b+s+k+b+q+s+q+c+q+e+q+q+c+q+b+q+c+q+k+q+c+q+c+q+c+q+e+e+q+k))("lambda s,q,b,k,c,e:print(b+s+k+b+q+s+q+c+q+e+q+q+c+q+b+q+c+q+k+q+c+q+c+q+c+q+e+e+q+k)","\"","(",")",",","\\")Best regards - Douglas Quine Wwquine.org