Python random chain quine
Impressed by the Japanese chain polyglot quine given in this habratopike , I, having previously met with quine programs, decided to get to know them more closely. After a quick googling and a brief reading of the wiki / blogs / sites on the topic, my hands were combed and I wanted to write my quine. Quine was written, even in several versions, but this seemed to me not enough. Later I even wrote a double quine (the python code generates the prolog code and the prolog code in turn is the original python code).
However, a question arose. Is it possible to write a quine of any order (i.e., one that will go into itself after N starts)? As it turned out, this is entirely possible. The result of the research was the following code:
The peculiarity of this code is that if you save it to the quine_20_0.py file and then execute the quine_20_0.py and quine_20_20.py files will match binary. Changing L, we can get a cycle of arbitrary length. For those who want to check whether this is so, I can actually provide a verification code:
This code creates a quine and runs the conversion. If successful (the file at the beginning and at the end matches), the code displays
If it is interesting, I can talk about the process and ideas for creating this quine (as a separate topic).
UPD . Some explanation of the principle is presented here .
However, a question arose. Is it possible to write a quine of any order (i.e., one that will go into itself after N starts)? As it turned out, this is entirely possible. The result of the research was the following code:
# xonix
L=19;B,Q,N,q,n=map(chr,(36,81,78,39,10))
X='import sys;sys.stdout.write(%s%s%s.replace(chr(36)+chr(81)+chr(36),chr(39)).replace(chr(36)+chr(81),chr(36)).replace(chr(36)+chr(78)+chr(36),chr(10)).replace(chr(36)+chr(78),chr(36)))'
Y='# xonix%sL=%s;B,Q,N,q,n=map(chr,(36,81,78,39,10))%sX=%s%s%s%sY=%s%s%s%sE="""%s""";exec E%simport sys;sys.stdout.write(b())'
E="""def b(l=L):
if l==L: Ql=q
else: Ql=B+Q*(L-l)+B;Nl=B+N*(L-l)+B
if l>0: return X%(Ql,b(l-1),Ql)
else: return Y%(Nl,str(L),Nl,Ql,X,Ql,Nl,Ql,Y,Ql,Nl,E.replace(n,Nl),Nl)""";exec E
import sys;sys.stdout.write(b())
The peculiarity of this code is that if you save it to the quine_20_0.py file and then execute the quine_20_0.py and quine_20_20.py files will match binary. Changing L, we can get a cycle of arbitrary length. For those who want to check whether this is so, I can actually provide a verification code:
python quine_20_0.py > quine_20_1.py
python quine_20_1.py > quine_20_2.py
python quine_20_2.py > quine_20_3.py
...
python quine_20_19.py > quine_20_20.py
# file: quine_n_gen.py
N = 20 # quine cycle
Q='''# xonix
L=${n};B,Q,N,q,n=map(chr,(36,81,78,39,10))
X='import sys;sys.stdout.write(%s%s%s.replace(chr(36)+chr(81)+chr(36),chr(39)).replace(chr(36)+chr(81),chr(36)).replace(chr(36)+chr(78)+chr(36),chr(10)).replace(chr(36)+chr(78),chr(36)))'
Y='# xonix%sL=%s;B,Q,N,q,n=map(chr,(36,81,78,39,10))%sX=%s%s%s%sY=%s%s%s%sE="""%s""";exec E%simport sys;sys.stdout.write(b())'
E="""def b(l=L):
if l==L: Ql=q
else: Ql=B+Q*(L-l)+B;Nl=B+N*(L-l)+B
if l>0: return X%(Ql,b(l-1),Ql)
else: return Y%(Nl,str(L),Nl,Ql,X,Ql,Nl,Ql,Y,Ql,Nl,E.replace(n,Nl),Nl)""";exec E
import sys;sys.stdout.write(b())'''.replace('${n}',str(N-1))
qName = 'quine_%s_0.py' % N
q = open(qName,'w')
q.write(Q)
q.close()
# test
import os
for i in range(N+1):
os.system('python quine_%s_%s.py > quine_%s_%s.py' % (N,i,N,i+1))
lastQName = 'quine_%s_%s.py' % (N,N)
print ':)' if open(qName).read()==open(lastQName).read() else ':('
* This source code was highlighted with Source Code Highlighter.
This code creates a quine and runs the conversion. If successful (the file at the beginning and at the end matches), the code displays
:)
. If it is interesting, I can talk about the process and ideas for creating this quine (as a separate topic).
UPD . Some explanation of the principle is presented here .