Хотя задача была отредактирована, чтобы показать, что чтение вашего источника разрешено, я уже создавал свое решение без этого. Итак, чтобы показать, что это возможно, я закончил. Нет чтения исходного файла:
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))
Попробуйте онлайн! (Обратите внимание, что это не изменит источник. Вы должны запустить его локально, чтобы это работало)
Для того, чтобы показать , что преобразования работают, вот тестовая программа ( в настоящее время создано , чтобы всегда выбрать 100
для r
, и выводит результат для каждой комбинации n
и p
для первоначального списка.)
Объяснение:
s='s=%r;print s%%s...';print s%s...
Первая строка - это ваша классическая квинна, но намного длиннее, чтобы учесть, что будет после.
from random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint
Импорт для случайных целых чисел. L
станет списком ординалов исходного кода, но изначально это целое число, которое не используется нигде в источнике для замены строки. Откройте файл, чтобы написать новый источник. При последующих запусках он откроется для добавления.
f.write("\n".join((s%s).split("\n")[1:5:2]).replace("4",`map(ord,s%s)`))
Удалите первую и третью строки кода. Замените 4
вышеприведенное списком порядковых чисел.
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))
По кусочкам:
if L>5:
- пропускает эту строку при первом исполнении. Позже L
будет список, и это запустится. Я объясню exec
последнее, потому что это не в первый раз.
n
- случайное число 0-2. Это определяет, какая модификация происходит (0 = вставить, 1 = заменить, 2 = удалить).
p
- Случайная позиция в списке, в которой произойдет изменение.
r
- случайное число для вставки или замены в списке
f.write("%03d"*3%(n,p,r))
- Добавьте 3 ранда в конец исходного файла. При каждом запуске это будет добавление к целому числу, которое кодирует все произошедшие изменения в исходном источнике.
exec'b=[];h=%d...'%1...
- Получить случайные числа (найденные позже %1
при последующих запусках), применить изменения к списку и распечатать.
while~-h:b+=[h%%1000];h/=1000
- Составьте список рандомов, сгенерированных до сих пор, с учетом лидирующих 1
, что предотвращает проблемы с лидирующими нулями.
while 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]
- (0 = вставить, 1 = заменить, 2 = удалить)
print"".join(map(chr,L))
- Распечатайте измененный источник.