 # Python random chain quine

Published on November 18, 2009

# 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:

```# 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 .