Програма Quine або Quine — це програма, яка виводить власний вихідний код під час виконання. Quine не може «вийти за межі себе», наприклад, роздрукувавши вміст файлу, що його містить, або використовуючи інтроспективні здібності для друку свого власного представлення. Замість цього він повинен розрахувати власний вихідний код.
Класичний спосіб створення такої програми відбувається в два етапи:
- Ініціалізація рядкової змінної за допомогою заповнювача для інтерполяції.
- Надрукуйте рядок і інтерполюйте його в себе .
Хитрість полягає в тому, щоб правильно натягнути струну. Як це зробити залежить від мови до мови та залежить від способу оголошення змінної, необхідності крапки з комою та нового рядка, необхідних лапок тощо. Цікавим є використання лапок; Треба знайти спосіб вказати, що лапки слід друкувати без фактичного використання лапок.
Баш
Як і більшість речей у Bash, ця програма використовує цікаву примху. Хоча одинарні лапки є сильними лапками і нічого не розширюють, інтерпретовані printf
вісімкові екрановані символи як символи з указаною кодовою точкою:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Пітон
У Python повертається специфікатор формату %r
автоматично одинарні лапки. Найпростіше, якщо код закінчується символом нового рядка:
s='s=%r;print(s%%s)';print(s%s)
Якщо вам потрібен код без розривів рядків, вам потрібно написати наступне:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Наступні сценарії JavaScript виконуються під node.js. ви використовуєте console.log
, який завжди додає новий рядок, тому новий рядок потрібен у кінці кожного сценарію:
s="s=%j;console.log(s,s)";console.log(s,s)
Наступна програма також цікава: вона не друкує своє повне представлення, але покладається на те, що функції мають певне представлення:
(function a(){console.log('('+a+')()')})()
Наступний приклад близький до шахрайства, оскільки він eval
використовується:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Іржа
Rust надає можливість взяти аргумент у лапки у форматованому макросі друку. Однак цей макрос вимагає, щоб перший аргумент макросу print був рядковим літералом! Тому найкраще використовувати позиційний ідентифікатор аргументу:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Ця програма PHP працює, зберігаючи вихідний код у рядку, а потім використовуючи цей рядок printf
виходи. The 39
означає символ ASCII '
, щоб правильно обробляти лапки в рядку:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
І останнє, але не менш важливе – HQ9+, розроблений Кліффом Біффлом:
Q