Brainfuck (англ. brain+fuck, укр. мозкоїб) — езотерична мова програмування, вигадана Урбаном Мюллером з метою забави. Складається з восьми команд, кожна з яких записується одним символом. Вихідний код програми на Brainfuck є послідовністю символів мови без жодного синтаксису.
Brainfuck | |
---|---|
Парадигма | езотерична |
Дата появи | 1993 |
Розробник | d |
Система типізації | відсутня |
Під впливом від | P′′ і FALSE |
Звичайні розширення файлів | .b, .bf |
|
Машина, якою керують команди Brainfuck, складається з упорядкованого набору комірок і покажчика поточної комірки, нагадуючи стрічку і голівку машини Тюринга. Крім того, в апараті наявний механізм взаємодії із зовнішнім світом (див. команди ,
, .
).
Команди мови
- 8 команд мови Brainfuck
>
— перейти до наступної комірки<
— перейти до попередньої комірки+
— збільшити значення в поточній комірці на 1-
— зменшити значення в поточній комірці на 1.
— надрукувати значення поточної комірки,
— ввести ззовні значення і зберегти в поточну комірку[
— якщо значення поточної комірки — нуль, перейти вперед по тексту програми до]
з урахуванням вкладеності]
— якщо значення поточної комірки не нуль, перейти назад по тексту програми до[
з урахуванням вкладеності
Попри зовнішню примітивність, мова Brainfuck з нескінченним набором комірок є повною за Тюрингом, але це зовсім не значить, що вона не поступається можливостями іншим сучасним мовам, подібним до C, Паскалю або Java, бо повнота за Тюрингом гарантує лише можливість зробити будь-яке числення, а є й ще інші аспекти, такі як багатонитковість, робота з пам'яттю тощо.
Brainfuck підходить для експериментів з генетичного програмування, що обумовлено простотою синтаксису, і, відповідно, генерації вихідного коду.
У «класичному» варіанті, що описаний Мюллером, розмір комірки — один байт, кількість комірок — 30 000.
У початковому стані покажчик розміщений в крайній лівій позиції, а всі комірки заповнені нулями. Збільшення/зменшення значень комірок відбувається за модулем 256. Введення та виведення також відбувається побайтово, з урахуванням кодування ASCII (тобто в результаті операції введення ,
символ 1 буде записаний у поточній комірці як число 0x31, а операція виведення .
, виконана над коміркою, що містить 0x41, надрукує латинську А). В інших варіантах мови розмір і кількість комірок можуть бути іншими (більшими). Існують версії, де значення комірок не є цілочисельним (із рухомою комою).
Порівняння команд з мовою С
Команди Brainfuck | Еквівалент у C |
---|---|
(Початок програми) | char array[30000]; |
> | ++ptr; |
< | --ptr; |
+ | ++*ptr; |
- | --*ptr; |
. | putchar(*ptr); |
, | *ptr=getchar(); |
[ | while (*ptr) { |
] | } |
Приклад програми
Код програми, що виводить «Hello World!»:
++++++++++[>+++++++>++++++++++>+++><<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Розбір програми:
Підготовка у пам'яті (із комірки 1) масиву значень, близьких до ASCII-кодів символів, котрі необхідно вивести (70, 100, 30, 10) через повторення 10 разів збільшення комірок на 7, 10, 3 та 1 відповідно | ||
++++++++++ | присвоювання комірці 0 (лічильнику) значення 10 | |
[ | повторювати, доки значення поточної комірки (комірки 0) більше нуля | |
>+++++++ | збільшення комірки 1 на 7 | |
>++++++++++ | збільшення комірки 2 на 10 | |
>+++ | збільшення комірки 3 на 3 | |
>+ | збільшення комірки 4 на 1 | |
<<<<- | повернення до комірки 0 (лічильника), і його зменшення на 1 | |
] | повернутися до початку циклу | |
Отримання кодів букв та їх вивід: | ||
>++. | Вивід «Н». Отримання коду «H» (72) із 70 у комірці 1 і вивід | |
>+. | Вивід «e». Отримання коду «e» (101) із 100 у комірці 2 і вивід | |
+++++++.. | Вивід «ll». Отримання коду «l» (108) із 101 у комірці 2 і вивід двічі | |
+++. | Вивід «o». Отримання коду «o» (111) із 108 у комірці 2 і вивід | |
>++. | Вивід пробілу. Отримання коду пробілу (32) із 30 у комірці 3 і вивід | |
<<+++++++++++++++. | Вивід «W». Отримання коду «W» (87) із 72 у комірці 1 і вивід | |
>. | Вивід «o». Код «o» (111) вже знаходиться у комірці 2, просто його виводимо | |
+++. | Вивід «r». Отримання коду «r» (114) із 111 у комірці 2 і вивід | |
------. | Вивід «l». Отримання коду «l» (108) із 114 у комірці 2 і вивід | |
--------. | Вивід «d». Отримання коду «d» (100) із 108 у комірці 2 і вивід | |
>+. | Вивід «!». Отримання коду «!» (33) із 32 у комірці 3 і вивід | |
>. | Вивід коду переводу рядка (10) із комірки 4 |
Приклади інтерпретаторів Brainfuck
Інтерпретатор мовою
#include <fstream> #include <iostream> #include <vector> using namespace std; static char cpu[30000]; int main(int argc, char **argv) { vector<char> acc; char ch; ifstream infile(argv[1]); while (infile) { infile.get(ch); acc.push_back(ch); } infile.close(); unsigned int j = 0; int brc = 0; for (int i = 0; i < acc.size(); ++i) { if (acc[i] == '>') j++; if (acc[i] == '<') j--; if (acc[i] == '+') cpu[j]++; if (acc[i] == '-') cpu[j]--; if (acc[i] == '.') cout << cpu[j]; if (acc[i] == ',') cin >> cpu[j]; if (acc[i] == '[') { if (!cpu[j]) { ++brc; while (brc) { ++i; if (acc[i] == '[') ++brc; if (acc[i] == ']') --brc; } } else continue; } else if (acc[i] == ']') { if (!cpu[j]) continue; else { if (acc[i] == ']') brc++; while (brc) { --i; if (acc[i] == '[') brc--; if (acc[i] == ']') brc++; } --i; } } } }
Інтерпретатор мовою Python
def block(code): opened = [] blocks = {} for i in range(len(code)): if code[i] == '[': opened.append(i) elif code[i] == ']': blocks[i] = opened[-1] blocks[opened.pop()] = i return blocks def parse(code): return ''.join(c for c in code if c in '><+-.,[]') def run(code): code = parse(code) x = i = 0 bf = {0: 0} blocks = block(code) l = len(code) while i < l: sym = code[i] if sym == '>': x += 1 bf.setdefault(x, 0) elif sym == '<': x -= 1 elif sym == '+': bf[x] += 1 elif sym == '-': bf[x] -= 1 elif sym == '.': print(chr(bf[x]), end='') elif sym == ',': bf[x] = int(input('Input: ')) elif sym == '[': if not bf[x]: i = blocks[i] elif sym == ']': if bf[x]: i = blocks[i] i += 1 code = input() run(code)
Інтерпретатор мовою C
#include <stdio.h> #define RAM 8 unsigned char cell[RAM]; char ptr = 0; void main(int argc, char *argv[]) { FILE *prg; if ((prg = fopen(argv[1], "rb")) == NULL) return; // INIT char com; while ((com = (char)getc(prg)) != EOF) { switch (com) { case '>': ptr++; if (ptr >= RAM) ptr--; break; case '<': ptr--; if (ptr < 0) ptr++; break; case '+': cell[ptr]++; break; case '-': cell[ptr]--; break; case '.': putc(cell[ptr], stdout); break; case ',': scanf("%d", &cell[ptr]); break; case '[': if (cell[ptr] == (char)0) { while (getc(prg) != ']') { } } break; case ']': if (cell[ptr] != (char)0) { do { fseek(prg, -2, SEEK_CUR); } while ((com = getc(prg)) != '['); } // IF break; } // SWITCH } // WHILE fclose(prg); }
Примітки
Посилання
- [[https://web.archive.org/web/20060324043721/http://www.muppetlabs.com/~breadbox/bf/ Архівовано 24 березня 2006 у Wayback Machine.] Оригінальний опис BF англійською і посилання на BF-ресурси]
Це незавершена стаття про мови програмування. Ви можете проєкту, виправивши або дописавши її. |
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Brainfuck angl brain fuck ukr mozkoyib ezoterichna mova programuvannya vigadana Urbanom Myullerom z metoyu zabavi Skladayetsya z vosmi komand kozhna z yakih zapisuyetsya odnim simvolom Vihidnij kod programi na Brainfuck ye poslidovnistyu simvoliv movi bez zhodnogo sintaksisu BrainfuckParadigma ezoterichnaData poyavi 1993Rozrobnik dSistema tipizaciyi vidsutnyaPid vplivom vid P i FALSEZvichajni rozshirennya fajliv b bf Mediafajli u Vikishovishi Mashina yakoyu keruyut komandi Brainfuck skladayetsya z uporyadkovanogo naboru komirok i pokazhchika potochnoyi komirki nagaduyuchi strichku i golivku mashini Tyuringa Krim togo v aparati nayavnij mehanizm vzayemodiyi iz zovnishnim svitom div komandi Komandi movi8 komand movi Brainfuck gt perejti do nastupnoyi komirki lt perejti do poperednoyi komirki zbilshiti znachennya v potochnij komirci na 1 zmenshiti znachennya v potochnij komirci na 1 nadrukuvati znachennya potochnoyi komirki vvesti zzovni znachennya i zberegti v potochnu komirku yaksho znachennya potochnoyi komirki nul perejti vpered po tekstu programi do z urahuvannyam vkladenosti yaksho znachennya potochnoyi komirki ne nul perejti nazad po tekstu programi do z urahuvannyam vkladenosti Popri zovnishnyu primitivnist mova Brainfuck z neskinchennim naborom komirok ye povnoyu za Tyuringom ale ce zovsim ne znachit sho vona ne postupayetsya mozhlivostyami inshim suchasnim movam podibnim do C Paskalyu abo Java bo povnota za Tyuringom garantuye lishe mozhlivist zrobiti bud yake chislennya a ye j she inshi aspekti taki yak bagatonitkovist robota z pam yattyu tosho Brainfuck pidhodit dlya eksperimentiv z genetichnogo programuvannya sho obumovleno prostotoyu sintaksisu i vidpovidno generaciyi vihidnogo kodu U klasichnomu varianti sho opisanij Myullerom rozmir komirki odin bajt kilkist komirok 30 000 U pochatkovomu stani pokazhchik rozmishenij v krajnij livij poziciyi a vsi komirki zapovneni nulyami Zbilshennya zmenshennya znachen komirok vidbuvayetsya za modulem 256 Vvedennya ta vivedennya takozh vidbuvayetsya pobajtovo z urahuvannyam koduvannya ASCII tobto v rezultati operaciyi vvedennya simvol 1 bude zapisanij u potochnij komirci yak chislo 0x31 a operaciya vivedennya vikonana nad komirkoyu sho mistit 0x41 nadrukuye latinsku A V inshih variantah movi rozmir i kilkist komirok mozhut buti inshimi bilshimi Isnuyut versiyi de znachennya komirok ne ye cilochiselnim iz ruhomoyu komoyu Porivnyannya komand z movoyu S Komandi Brainfuck Ekvivalent u C Pochatok programi char array 30000 br char ptr array gt ptr lt ptr ptr ptr putchar ptr ptr getchar while ptr Priklad programiKod programi sho vivodit Hello World gt gt gt gt lt lt lt lt gt gt gt lt lt gt gt gt Rozbir programi Pidgotovka u pam yati iz komirki 1 masivu znachen blizkih do ASCII kodiv simvoliv kotri neobhidno vivesti 70 100 30 10 cherez povtorennya 10 raziv zbilshennya komirok na 7 10 3 ta 1 vidpovidno prisvoyuvannya komirci 0 lichilniku znachennya 10 povtoryuvati doki znachennya potochnoyi komirki komirki 0 bilshe nulya gt zbilshennya komirki 1 na 7 gt zbilshennya komirki 2 na 10 gt zbilshennya komirki 3 na 3 gt zbilshennya komirki 4 na 1 lt lt lt lt povernennya do komirki 0 lichilnika i jogo zmenshennya na 1 povernutisya do pochatku ciklu Otrimannya kodiv bukv ta yih vivid gt Vivid N Otrimannya kodu H 72 iz 70 u komirci 1 i vivid gt Vivid e Otrimannya kodu e 101 iz 100 u komirci 2 i vivid Vivid ll Otrimannya kodu l 108 iz 101 u komirci 2 i vivid dvichi Vivid o Otrimannya kodu o 111 iz 108 u komirci 2 i vivid gt Vivid probilu Otrimannya kodu probilu 32 iz 30 u komirci 3 i vivid lt lt Vivid W Otrimannya kodu W 87 iz 72 u komirci 1 i vivid gt Vivid o Kod o 111 vzhe znahoditsya u komirci 2 prosto jogo vivodimo Vivid r Otrimannya kodu r 114 iz 111 u komirci 2 i vivid Vivid l Otrimannya kodu l 108 iz 114 u komirci 2 i vivid Vivid d Otrimannya kodu d 100 iz 108 u komirci 2 i vivid gt Vivid Otrimannya kodu 33 iz 32 u komirci 3 i vivid gt Vivid kodu perevodu ryadka 10 iz komirki 4Prikladi interpretatoriv BrainfuckInterpretator movoyu C include lt fstream gt include lt iostream gt include lt vector gt using namespace std static char cpu 30000 int main int argc char argv vector lt char gt acc char ch ifstream infile argv 1 while infile infile get ch acc push back ch infile close unsigned int j 0 int brc 0 for int i 0 i lt acc size i if acc i gt j if acc i lt j if acc i cpu j if acc i cpu j if acc i cout lt lt cpu j if acc i cin gt gt cpu j if acc i if cpu j brc while brc i if acc i brc if acc i brc else continue else if acc i if cpu j continue else if acc i brc while brc i if acc i brc if acc i brc i Interpretator movoyu Python def block code opened blocks for i in range len code if code i opened append i elif code i blocks i opened 1 blocks opened pop i return blocks def parse code return join c for c in code if c in gt lt def run code code parse code x i 0 bf 0 0 blocks block code l len code while i lt l sym code i if sym gt x 1 bf setdefault x 0 elif sym lt x 1 elif sym bf x 1 elif sym bf x 1 elif sym print chr bf x end elif sym bf x int input Input elif sym if not bf x i blocks i elif sym if bf x i blocks i i 1 code input run code Interpretator movoyu C include lt stdio h gt define RAM 8 unsigned char cell RAM char ptr 0 void main int argc char argv FILE prg if prg fopen argv 1 rb NULL return INIT char com while com char getc prg EOF switch com case gt ptr if ptr gt RAM ptr break case lt ptr if ptr lt 0 ptr break case cell ptr break case cell ptr break case putc cell ptr stdout break case scanf d amp cell ptr break case if cell ptr char 0 while getc prg break case if cell ptr char 0 do fseek prg 2 SEEK CUR while com getc prg IF break SWITCH WHILE fclose prg PrimitkiPosilannya https web archive org web 20060324043721 http www muppetlabs com breadbox bf Arhivovano24 bereznya 2006 u Wayback Machine Originalnij opis BF anglijskoyu i posilannya na BF resursi Ce nezavershena stattya pro movi programuvannya Vi mozhete dopomogti proyektu vipravivshi abo dopisavshi yiyi