Quine

Program qu ine lub quine to program, który po wykonaniu drukuje swój własny kod źródłowy. Quine nie może "wychodzić poza siebie", na przykład poprzez drukowanie zawartości pliku, w którym jest zawarty lub używanie zdolności introspekcyjnych do drukowania własnej reprezentacji. Zamiast tego musi obliczyć swój własny kod źródłowy.


Klasyczny sposób tworzenia takiego programu składa się z dwóch kroków:

  1. Inicjuje zmienną łańcuchową z symbolem zastępczym dla interpolacji.
  2. Wypisuje ciąg znaków i interpoluje go do siebie.

Sztuczka polega na tym, aby ciąg znaków był poprawny. Sposób, w jaki to zrobisz, różni się w zależności od języka i zależy od deklaracji zmiennych, potrzeby stosowania średników i podziałów wierszy, wymaganych cudzysłowów itp.

Bash

Podobnie jak większość rzeczy w Bashu, ten program wykorzystuje interesujące dziwactwo. Chociaż pojedyncze cudzysłowy są silnymi cudzysłowami i niczego nie rozszerzają, to printf ósemkowe znaki specjalne jako znaki z określonym punktem kodowym:

s='s=%s;printf "$s" "$s"';printf "$s" "$s"

Python

W języku Python identyfikator formatu %r Najprostszym sposobem na to jest zakończenie kodu znakiem nowej linii:

s='s=%r;print(s%%s)';print(s%s)

Jeśli chcesz, aby kod nie zawierał podziału wiersza, musisz napisać następujące polecenie:

s='s=%r;print(s%%s,sep="")';print(s%s,sep="")

JavaScript

Poniższe zapytania JavaScript działają pod node.js. Używają one console.log, która zawsze dodaje nową linię, więc nowa linia jest wymagana na końcu każdego skryptu:

s="s=%j;console.log(s,s)";console.log(s,s)

Poniższy program jest również interesujący: nie drukuje całej swojej reprezentacji, ale opiera się na fakcie, że funkcje mają określoną reprezentację:

(function a(){console.log('('+a+')()')})()

Następny przykład jest bliski oszustwa, ponieważ eval używany:

code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)

Rdza

Rust zapewnia sposób cytowania argumentu w sformatowanym makrze drukowania, ale to makro wymaga, aby pierwszy argument makra drukowania był literałem łańcuchowym! Dlatego najlepiej jest użyć pozycyjnego identyfikatora argumentu:

fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}

PHP

Ten program PHP działa poprzez zapisanie kodu źródłowego w łańcuchu znaków, a następnie użycie funkcji printf The 39 oznacza znak ASCII ', aby poprawnie obsługiwać cudzysłowy w ciągu znaków:

<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);

HQ9+

Ostatnim, ale nie mniej ważnym produktem jest HQ9+, który został opracowany przez Cliffa Biffle'a:

Q
Plecy