Pull to refresh

Comments 8

Для повышения полезности статьи запрашиваю описание как это делается и на сколько просто/сложно сделать из n=2 в n=3?
impwx верно подметил.
У меня на этот квайн ушло 3 вечера, из n=2 в n=3 не могу сказать сколько времени займет, но попробовать стоит. :)
Я попробовал написать для цепочки C -> Brainfuck -> C. Заняло примерно час времени, код на C меньше 500 байт. Но пока не успел проверить :)
Собственно, вот код на C:

main(){ char *s="main(){ char *s=\0\
; int i,j; for(i=0;i<269;i++){ for(j=s[i];j--;) putchar(43); putchar(62); } puts(s+107);}\0\
+++++++[>+++++>+++++++++++++>+++++++<<<-]>->+>-<<<<[<]<[<]<[<]>[.>]>[>]>[>]>.<<[<]<[<]<[<]>[.>]>[>]>[>]>>.>.\
<<<<[<]<[<]>[.>]>[>]>>.>.<<<<[<]>[.>]>.<<[<]<[<]>[.>],"; 
int i,j; for(i=0;i<269;i++){ for(j=s[i];j--;) putchar(43); putchar(62); } puts(s+107);}

Предполагается, что по команде "," программа на BF не запрашивает символ, а останавливается.
После первой итерации C+BF получается программа без переводов строки, а результат второй итерации совпадает с результатом первой.
Код на Brainfuck выглядит примерно так (в переводе на человеческий язык):
S1="main(){ char *s="
S2="; int i,j; for(i=0;i<269;i++){ for(j=s[i];j--;) putchar(43); putchar(62); } puts(s+107);}";
S3="+++++++[>+++++>+++++++++++++>+++++++<<<-]>->+>-<<<<[<]<[<]<[<]>[.>]>[>]>[>]>.<<[<]<[<]<[<]>[.>]>[>]>[>]>>.>.\
<<<<[<]<[<]>[.>]>[>]>>.>.<<<<[<]>[.>]>.<<[<]<[<]>[.>],"; 
S4="\"\\0";
print(S1);
print(S4[0]);
print(S1);
print(S4[1]); print(S4[2]);
print(S2);
print(S4[1]); print(S4[2]);
print(S3);
print(S4[0]);
print(S2);


А можно узнать (в порядке повышения эрудиции) стратегию формирования квайнов? Какие-нибудь шаблонные действия и их комбинации, приводящие к решению, как, скажем, в судоку и других головоломках?
Для обычного квайна обычно используется строка с placeholder'ом, на место которого подставляется она же сама для достижения рекурсии. Можно почитать более подробно в теме на StackOverflow.
А цепной квайн на С можно написать, например, так:
main(){char*s1="main(){char*s1=%c%s%c,*s2=%c%s%c;printf(s1,34,s1,34,34,s2,34,34,37,34);printf(%c%cd%c,(",
*s2="+1)%c43);printf(s2,37);}";
printf(s1,34,s1,34,34,s2,34,34,37,34);printf("%d",(15+1)%43);printf(s2,37);}

Число в выражении (15+1)%43 будет крутиться по модулю указанного числа (в этом примере — перебирать значения от 0 до 42).
Sign up to leave a comment.

Articles