📜 ⬆️ ⬇️

Chain quine of arbitrary order in Python

I was impressed with the chain polyglotted quine of the Japanese cited in this habratopic , I, who had previously met with quine programs, decided to get to know them more closely. After a quick googling and short reading of wiki / blogs / sites on the topic, my hands were itching and I wanted to write my quine. Quine was written, even in several versions, but it seemed to me a little. Later I even wrote a double quine (the python code generates the code for prolog and the code for prolog in turn the original python code).

However, there was a question. Is it possible to write a quine of any order (that is, one that will go over into itself after N starts)? As it turned out, it is quite possible. The result of the survey 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*(Ll)+B;Nl=B+N*(Ll)+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())



A feature of this code is that if you save it to the file quine_20_0.py and then execute
')
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


then the files quine_20_0.py and quine_20_20.py will match in binary. Changing L, we can obtain a cycle of arbitrary length.

For those who want to check whether this is true, I can actually provide a verification code:

# 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*(Ll)+B;Nl=B+N*(Ll)+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 drives the conversion. In case of success (the file at the beginning and at the end is the same), the code displays :) .

If it is interesting, I can tell you about the process and ideas for creating this quine (as a separate topic).

UPD . Some explanation of the principle presented here .

Source: https://habr.com/ru/post/75663/


All Articles