Meskipun tantangan telah diedit untuk menunjukkan bahwa membaca sumber Anda diperbolehkan, saya sudah membuat solusi tanpa itu. Jadi, untuk menunjukkan bahwa itu mungkin, saya menyelesaikannya. Tidak ada pembacaan file sumber:
s='s=%r;print s%%s\nfrom random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint\nf.write("\\n".join((s%%s).split("\\n")[1:5:2]).replace("4",`map(ord,s%%s)`))\nif L>5:exec\'b=[];h=%%d\\nwhile~-h:b+=[h%%%%1000];h/=1000\\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\\nprint"".join(map(chr,L))\'%%1\n\nn=R(0,2);p=R(0,len(L if L>5else s%%s));r=R(0,255);f.write("%%03d"*3%%(n,p,r))';print s%s
from random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint
f.write("\n".join((s%s).split("\n")[1:5:2]).replace("4",`map(ord,s%s)`))
if L>5:exec'b=[];h=%d\nwhile~-h:b+=[h%%1000];h/=1000\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\nprint"".join(map(chr,L))'%1
n=R(0,2);p=R(0,len(L if L>5else s%s));r=R(0,255);f.write("%03d"*3%(n,p,r))
Cobalah online! (Perhatikan bahwa ini tidak akan mengubah sumber. Anda harus menjalankannya secara lokal agar dapat berfungsi)
Untuk menunjukkan bahwa transformasi bekerja, di sini adalah program uji (saat ini dibentuk untuk selalu memilih 100
untuk r
, dan mencetak hasil untuk setiap kombinasi n
dan p
untuk daftar awal.)
Penjelasan:
s='s=%r;print s%%s...';print s%s...
Baris pertama adalah quine klasik Anda, tetapi lebih lama untuk menjelaskan apa yang terjadi setelahnya.
from random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint
Impor untuk bilangan bulat acak. L
akan menjadi daftar tata cara kode sumber, tetapi pada awalnya merupakan bilangan bulat yang tidak digunakan di tempat lain dalam sumber untuk memungkinkan penggantian string. Buka file untuk menulis sumber baru. Pada menjalankan selanjutnya, itu akan terbuka untuk menambahkan.
f.write("\n".join((s%s).split("\n")[1:5:2]).replace("4",`map(ord,s%s)`))
Hapus baris kode pertama dan ketiga. Ganti yang di 4
atas dengan daftar tata cara.
if L>5:exec'b=[];h=%d\nwhile~-h:b+=[h%%1000];h/=1000\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\nprint"".join(map(chr,L))'%1
n=R(0,2);p=R(0,len(L if L>5else s%s));r=R(0,255);f.write("%03d"*3%(n,p,r))
Dalam potongan:
if L>5:
- Melewati baris ini pada eksekusi pertama. Nantinya, L
akan ada daftar, dan ini akan berjalan. Saya akan menjelaskan yang exec
terakhir, karena ini tidak berjalan pertama kali.
n
- Angka acak 0-2. Ini menentukan modifikasi yang terjadi (0 = masukkan, 1 = ganti, 2 = hapus).
p
- Posisi acak dalam daftar tempat modifikasi akan terjadi.
r
- Nomor acak untuk dimasukkan atau diganti dalam daftar
f.write("%03d"*3%(n,p,r))
- Tambahkan 3 tebusan ke akhir file sumber. Setiap kali dijalankan, ini akan menambahkan bilangan bulat yang menyandikan semua perubahan ke sumber awal yang telah terjadi.
exec'b=[];h=%d...'%1...
- Dapatkan nomor acak (ditemukan setelah %1
dijalankan nanti), terapkan perubahan pada daftar, dan cetak.
while~-h:b+=[h%%1000];h/=1000
- Buat daftar tebusan yang dihasilkan sejauh ini, yang bertanggung jawab atas yang memimpin 1
, yang mencegah masalah dengan angka nol di depan.
while b:r,p,n=b[-3:];b=b[:-3]
- Tetapkan tebusan untuk iterasi ini.
L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]
- (0 = masukkan, 1 = ganti, 2 = hapus)
print"".join(map(chr,L))
- Cetak sumber yang dimodifikasi.