Brainfuck

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 20. června 2022; kontroly vyžadují 7 úprav .
Brainfuck
Jazyková třída esoterický
Objevil se v 1993
Autor Urban Muller
Vývojář Urban Müller [d]
Přípona souboru .bnebo.bf
Dialekty BrainSub, Brainfork, Brainloller, COW, Ook, Pbrain, Smallfuck, Spoon , LOLCODE , Whitespace , DoubleFuck , Feckfeck
Byl ovlivněn NEPRAVDIVÉ
 Mediální soubory na Wikimedia Commons

Brainfuck je jeden z esoterických programovacích jazyků , vynalezený Urbanem Müllerem v roce 1993 , známý pro svůj minimalismus .  Název jazyka lze do ruštiny přeložit jako odstranění mozku , je přímo odvozen z anglického výrazu brainfuck ( mozek - mozek, fuck - fuck ), tedy zaplétat se do nesmyslů . Jazyk má osm příkazů, z nichž každý je napsán jedním znakem. Zdrojový kód programu Brainfuck je sekvence těchto znaků bez jakékoli další syntaxe.

Jedním z motivů Urbana Mullera bylo vytvořit jazyk s co nejmenším překladačem. Částečně byl inspirován jazykem FALSE , pro který existoval 1024bytový kompilátor. Existují překladače jazyka Brainfuck menší než 200 bajtů [1] . Programování v jazyce Brainfuck se píše obtížně, pro což se mu někdy říká jazyk pro masochisty. Ale zároveň je Brainfuck zcela přirozený, úplný a jednoduchý jazyk a lze jej použít při definování pojmu vyčíslitelnosti .

Stroj, ovládaný příkazy Brainfuck , sestává z uspořádané sady buněk a ukazatele na aktuální buňku, připomínající pásku a hlavu Turingova stroje . Kromě toho zahrnuje zařízení pro komunikaci s vnějším světem (viz příkazy . a , ) prostřednictvím vstupního toku a výstupního toku.

Jazyk Brainfuck lze popsat pomocí ekvivalentů jazyka C :

Tým Brainfuck C ekvivalent Popis týmu
Spuštění programu int i = 0;
char arr[30000];
memset(arr, 0, sizeof(arr));
paměť je alokována pro 30 000 buněk s nulovými počátečními hodnotami
> i++; přesunout do další buňky
< i--; přesunout do předchozí buňky
+ arr[i]++; zvýšit hodnotu v aktuální buňce o 1
- arr[i]--; snížit hodnotu v aktuální buňce o 1
. putchar(arr[i]); vytisknout hodnotu z aktuální buňky
, arr[i] = getchar(); zadejte hodnotu zvenčí a uložte ji do aktuální buňky
[ while(arr[i]){ pokud je hodnota aktuální buňky nula, posuňte se v textu programu dopředu na znak následující za odpovídajícím ] (včetně vnoření)
] } pokud hodnota aktuální buňky není nula, vraťte se přes text programu ke znaku [ (s přihlédnutím k vnoření)

Navzdory vnější primitivitě má Brainfuck s nekonečnou sadou buněk Turingovu úplnost , a proto není z hlediska potenciálu horší než „skutečné“ jazyky jako C , Pascal nebo Java .

Brainfuck je vhodný pro experimenty v genetickém programování díky jednoduchosti syntaxe, a tedy i generování zdrojového kódu.

V "klasickém" Brainfuck popsaném Mullerem je velikost buňky jeden bajt, počet buněk je 30 000. V počátečním stavu je ukazatel na pozici úplně vlevo a všechny buňky jsou vyplněny nulami. Hodnoty buněk se zvyšují nebo snižují modulo 256. Vstup/výstup probíhá také bajt po bajtu, přičemž se bere v úvahu kódování ASCII (to znamená, že v důsledku operace vstupu ( , ) bude znak 1 zapsán do aktuální buňky jako číslo 0x31 (49) a výstupní operace ( . ) provedená na buňce obsahující 0x41 (65) vytiskne latinku A ). V jiných jazykových variantách může být velikost a počet buněk jiný (větší). Existují verze, kde hodnota buněk není celé číslo (s plovoucí desetinnou čárkou).

Příklad programu

Brainfuck krok za krokem program, který vytiskne Hello World! » se zalomením řádku (ve formě ASCII kódu - 72 101 108 108 111 32 87 111 114 108 100 33 10): +++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++ . +++++++++++++++++++ ++++++++++++ . +++++++ .. +++ . -------------------- -------------------------------------------------- -- ---------------- . +++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ . ++++++++++++++++++++++ ++++++ . +++ . ------ . -------- . ------------------- -------------------------------------------------- -- ---- . ----------------------- .

Celkem bylo použito 389 výpisů a 1 paměťová buňka. Optimalizovaný program je znatelně kratší – pouze 111 příkazů, ale 5 paměťových buněk. První buňka se používá jako počítadlo smyček pro 10 iterací, další buňky obsahují čísla 7, 10, 3 a 1 , zvětšená o tuto smyčku na 70, 100, 30 a 10 , k součtu dojde před tiskem, druhé slovo je postavený z pozůstatků prvního:

++++++++++ [ > +++++++ > ++++++++++ > +++ > + <<<< - ] > ++ . > + . +++++++ .. +++ . > ++ . << +++++++++++++++++ . > . +++ . ------ . -------- . > + . > .

Analýza programu:

Cyklus vycpávání hlavních čísel
++++++++++ přiřadit buňce 0 hodnotu 10
[ opakujte příkazy popsané touto závorkou, dokud hodnota aktuální buňky 0 nebude rovna nule
>+++++++ zvýšení buňky o 1 x 7
>++++++++++ zvýšení buňky o 2 x 10
>+++ zvýšení buňky 3x3
>+ přírůstek buňky 4x1
<<<<- zmenšení buňky 0 o 1
] kontrola, zda je buňka 0 nula
Výstup prvního slova
>++. v buňce 1 , přidání 2 k 70 a vytištění ASCII kódu 72, tzn. písmena " H ".
>+. v buňce 2 přidejte 1 k 100 = 101, vytiskněte písmeno " e "
+++++++.. ve stejné buňce přidáním 7 k 101 = 108, vytištění " l " dvakrát
+++. ve stejné buňce přidání 3 k 108 = 111, tisk " o "
>++. v buňce 3 přidejte 2 k 30 = 32, vytiskněte mezeru
Výstup druhého slova s ​​opětovným použitím buňky
<<+++++++++++++++. v buňce 1 přidejte 15 k 72 = 87, vytiskněte " W "
>. buňka 2 již má 111, okamžitě vytiskněte " o "
+++. ve stejné buňce přidání 3 k 111 = 114, tisk " r "
------. ve stejné buňce odečtěte 6 od 114 = 108, vytiskněte " l "
--------. ve stejné buňce odečtěte 8 od 108 = 100, vytiskněte " d "
>+. v buňce 3 přidejte 1 k 32 = 33, vytiskněte " ! »
>. buňka 4 již má 10, okamžitě vytiskněte posun řádku

Brainfuck tlumočník

Perl

Příklad tlumočníka Brainfuck napsaného v Perlu :

#!/usr/bin/perl open F , shift ; @code = grep { /[+-\.,\[\]><]/ } rozdělení '' , <F> ; for ( my $_ = 0 ; $_ < @code ; ++ $_ ) { ++ $cpu [ $i ] if $code [ $_ ] eq '+' ; -- $cpu [ $i ] if $code [ $_ ] eq '-' ; -- $i if $code [ $_ ] eq '<' ; ++ $i if $code [ $_ ] eq '>' ; print chr $cpu [ $i ] if $code [ $_ ] eq '.' ; $cpu [ $i ] = ord <STDIN> if $code [ $_ ] eq ',' ; if ( $code [ $_ ] eq '[' ) { if ( ! $cpu [ $i ]) { ++ $brc ; while ( $brc ) { ++ $_ ; ++ $brc if $code [ $_ ] eq '[' ; -- $brc if $code [ $_ ] eq ']' ; } } else { další ; } } elsif ( $kód [ $_ ] eq ']' ) { if ( ! $cpu [ $i ]) { další ; } else { ++ $brc if $code [ $_ ] eq ']' ; while ( $brc ) { -- $_ ; -- $brc if $code [ $_ ] eq '[' ; ++ $brc if $code [ $_ ] eq ']' ; } -- $_ ; } } }

C++

Příklad překladače Brainfuck napsaného v C++ :

#include <iostream> #include <fstream> #include <vektor> #include <iterátor> int main ( int argc , char ** argv ) { std :: soubor fstream ( argv [ 1 ], std :: ios :: in ); std :: istreambuf_iterator < char > fstart ( soubor ), fend ; std :: vector < char > itape ( fstart , fend ); soubor . zavřít (); std :: vector < char > mtape ( 30000 , 0 ); std :: vector < char >:: iterátor m = mtape . začít (); std :: vector < char >:: iterator i = itape . začít (); int b = 0 ; for (; i != itape . end (); ++ i ) { přepínač ( * i ) { případ '>' : if ( ++ m == mtape . end ()) { mtape . zatlačení ( 0 ); m = -mtape . _ konec (); } zlomit ; případ '<' : -- m ; zlomit ; případ '+' : +** m ; zlomit ; případ '-' : --* m ; zlomit ; případ '.' : std :: cout << * m ; zlomit ; case ',' : std :: cin >> * m ; zlomit ; případ '[' : if ( * m ) pokračovat ; ++ b ; zatímco ( b ) přepínač ( *++ i ){ případ '[' : ++ b ; zlomit ; case ']' : -- b ; zlomit ; } zlomit ; případ ']' : if ( !* m ) pokračovat ; ++ b ; zatímco ( b ) přepínač ( *-- i ){ case '[' : -- b ; zlomit ; případ ']' : ++ b ; zlomit ; } --i ; _ zlomit ; } } }

Brainfuck programování

Každý začátečník programování Brainfuck okamžitě narazí na následující problémy:

Tyto problémy lze vyřešit.

Označte @(k) posun o k buněk doprava, pokud k>0, a doleva, pokud k<0 V souladu s tím @(k) = >… k krát …> nebo <… -k krát …<
nula(): vynulování aktuální buňky: [-] = [+]
add(k): přidání hodnoty buňky n (aktuální) k hodnotě buňky n+k: [ - @(k) + @(-k) ] v tomto případě se hodnota buňky n ztratí (vynuluje).
mov(k): zkopírování hodnoty buňky n (aktuální) do buňky n+k se ztrátou (vynulováním) hodnoty buňky n: @(k) nula() @(-k) přidat(k) = @(k) [-] @(-k) [ - @(k) + @(-k) ]
copy(k,t): zkopíruje hodnotu buňky n (aktuální) do buňky n+k pomocí mezilehlé buňky n + k + t, díky čemuž nedochází ke ztrátě (uložení) hodnoty buňky n. @(k) nula() @(t) nula() @(-kt) [ - @(k) + @(t) + @(-kt) ] @(k+t) mov(-kt) = @(k) [-] @(t) [-] @(-kt) [ — @(k) + @(t) + @(-kt) ] @(k+t) [ — @(-kt) + @(k+t) ]
ifelse(t): pokud aktuální buňka>0, pak true pokud je aktuální buňka = 0, pak je podmínka nepravdivá t-relativní počet pomocných buněk: @(t)[-]+@(-t) nastaví příznak 1 pro případ else [ zde větve akce pravda @(t)[-]@(-t) nastaví příznak 0 pro jiný případ [-] výstup smyčky ] @(t) [@(-t) zde akce větve nepravdivé @(t)[-] ukončení smyčky ] @(-t-1)

Brainfuck se téměř vůbec nepoužívá k praktickému programování (s výjimkou práce jednotlivých nadšenců) a používá se hlavně na hádanky a soutěžní problémy.

Jazyky založené na Brainfuck

Poznámky: 1. Speciálně pro funkčnost příkazu mOO jsou vnitřní kódy jeho příkazů [2] zavedeny do jazyka COW , v tabulce jsou uvedeny v samostatném sloupci. 2. Nepřítomnost týmu je označena jako nepřítomnost .

Brainfuck OK! KRÁVA COW kód Popis
] OK? OK! bučení 0 Konec cyklu
< OK? OK. bučení jeden Předchozí buňka
> OK. OK? bučení 2 Další buňka
ots. ots. bučení 3 Proveďte hodnotu v aktuální buňce jako příkaz s odpovídajícím kódem z rozsahu 0 - 11; kód 3 způsobí smyčku
ots. ots. Bučení čtyři Pokud je hodnota aktuální buňky nula, zadejte ji z klávesnice; pokud hodnota aktuální buňky není nula, zobrazte ji na obrazovce
- OK! OK! Bučení 5 Hodnota aktuální buňky se sníží o 1
+ OK. OK. Bučení 6 Hodnota aktuální buňky se zvýší o 1
[ OK! OK? MO 7 Spuštění smyčky (COW má funkci - první příkaz smyčky je přeskočen)
[-] ots. OOO osm Obnoví hodnotu v aktuální buňce
ots. ots. MMM 9 Pokud je registr prázdný, zkopírujte do něj hodnotu aktuální buňky, jinak zkopírujte obsah registru do buňky a vymažte registr
. OK! OK. OOM deset Zobrazení hodnoty aktuální buňky
, OK. OK! oom jedenáct Dotaz na hodnotu aktuální buňky

Viz také

Dialekty a realizace

Další popis mnoha dialektů tohoto jazyka lze nalézt ve wiki encyklopedii esoterických jazyků [3]

Další abstraktní implementátoři a formální výpočetní systémy

Poznámky

  1. Například 166 bajtový zdroj kompilátoru (odkaz není k dispozici) . Datum přístupu: 18. srpna 2010. Archivováno z originálu 19. srpna 2010. 
  2. COW - dialekt programovacího jazyka Brainfuck - Encyklopedie programovacích jazyků . Získáno 11. prosince 2020. Archivováno z originálu dne 5. května 2021.
  3. Kategorie:Brainfuck_derivatives Archivováno 14. dubna 2012 na Wayback Machine , esolangs.org

Odkazy