Под катом вы найдете самую ненормальную реализацию интерпетатора Brainfuck с помощью нормальных алгоритмов Маркова. В этой реализации все операторы Brainfuckа и сам интерпретатор являются нормальными алгоритмами Маркова. Целью этого поста было рассмотреть Brainfuck с точки зрения классической теории алгоритмов и привести его реализацию с помощью какого-либо классического уточнения понятия алгоритма. Кто не боится причинить своему мозгу вред столь ненормальным программированием добро пожаловать (под катом много текста, иногда сложного для понимания если не знаком с теорией алгоритмов, но в конце поста есть ссылка на реализацию этого интерперетатора, который можно попробовать в действии). Его быстродействие, по понятным причинам не очень высоко, но с точки зрения понимания алгоритмов работы он очень наглядный.
Все началось с того, что масса постов о Brainfuck на хабре подбила меня все же выучить что это такое. Кроме того на этот пост меня натолкнул мой друг, тоже программист, который сказал что-то вроде:«Раз ты мучаешь студентов в универе этой теорией алгоритмов, то опиши интерпретатор Brainfuck с помощью примитивно рекурсивной функции». Эта фраза и плохая погода и настроение и подтолкнула к тому, что получилось. Поскольку хабр ИТ а не математический ресурс, то вместо реализации с помощью рекурсивных функций мне показалось более правильным сделать реализацию с помощью нормальных алгоритмов Маркова.
Чтобы познакомиться с основными понятиями, которые будут встречаться можно почитать:
Brainfuck;
Рекурсивные функции;
Нормальный алгоритм Маркова.
Как известно, Brainfuck является Тьюринг полным языком, что теоретически позволяет реализовать с его помощью любой алгоритм. Давайте посмотрим чем же является Brainfuck с точки зрения теории алгоритмов. Наиболее точно можно охарактеризовать его как некий гибрид машины Тьюринга и машины с натуральнозначными регистрами. Поскольку Brainfuck является Тьюринг полным, то значит его можно реализовать как на машине с натуральнозначными ре��истрами так и на машине Тьюринга, рекурсивных функциях, алгоритмах Маркова(чем я и занялся).
И так, что реализовано:
Что нужно для реализации интерпретатора на нормальных алгоритмах Маркова: строка, в которую будем вводить код на брейнфаке(без оператора "," ), строка выполняющая роль ленту памяти, строка буффера(для вывода результата), строка для вывода результата.
При начале работе интерпретатора строка-лента должна иметь вид
._…
Количество точек — это количество доступных ячеек памяти, символ _ — указатель на текущую ячейку.
Продукции алгорима Маркова будем задавать в виде двух массивов строк одинаковой длины: первый — левые части продукций, второй — правые. Если правая часть продукции заканчивается на FIN, то это значит что эта продукция будет финальной.
Начнем с того, что проще — реализация операций брейнфака алгоритмами Маркова.
Ну и теперь собственно нормальный алгоритм-интерпретатор. Выполняется на строке-исходнике, после каждой продукции вызывается подалгоритм из таблицы операций(см. выше).
У Вас есть возможность выполнить всю программу сразу или выполнять ее шаг за шагом. Реализация на С#, так что для ее работы нужен установленный .NET 2.0.
Демонстарция работа классического Hello World! на Brainfuck на этом интерпретаторе.

P.S. Надеюсь это было хоть кому-нибудь интересно. Старался уложится �� максимально небольшой объем текста.
Реализация интерпретатора. Можете попробовать этого монстрика в работе.
Как родилась такая идея
Все началось с того, что масса постов о Brainfuck на хабре подбила меня все же выучить что это такое. Кроме того на этот пост меня натолкнул мой друг, тоже программист, который сказал что-то вроде:«Раз ты мучаешь студентов в универе этой теорией алгоритмов, то опиши интерпретатор Brainfuck с помощью примитивно рекурсивной функции». Эта фраза и плохая погода и настроение и подтолкнула к тому, что получилось. Поскольку хабр ИТ а не математический ресурс, то вместо реализации с помощью рекурсивных функций мне показалось более правильным сделать реализацию с помощью нормальных алгоритмов Маркова.
Чтобы познакомиться с основными понятиями, которые будут встречаться можно почитать:
Brainfuck;
Рекурсивные функции;
Нормальный алгоритм Маркова.
Собственно полнейший Brainfuck
Как известно, Brainfuck является Тьюринг полным языком, что теоретически позволяет реализовать с его помощью любой алгоритм. Давайте посмотрим чем же является Brainfuck с точки зрения теории алгоритмов. Наиболее точно можно охарактеризовать его как некий гибрид машины Тьюринга и машины с натуральнозначными регистрами. Поскольку Brainfuck является Тьюринг полным, то значит его можно реализовать как на машине с натуральнозначными ре��истрами так и на машине Тьюринга, рекурсивных функциях, алгоритмах Маркова(чем я и занялся).
И так, что реализовано:
| Команда Brainfuck |
Описание команды |
Реализовано? |
| > |
перейти к следующей ячейке |
Реализовано. |
| < |
перейти к предыдущей ячейке |
Реализовано. |
| + |
увеличить значение в текущей ячейке на 1 |
Реализовано. |
| - |
уменьшить значение в текущей ячейке на 1 |
Реализовано. |
| . |
напечатать значение из текущей ячейки |
Реализовано. |
| , |
ввести извне значение и сохранить в текущей ячейке |
Не реализовано, так эта операция не представляет особого интереса с точки зрения алгоритмов Маркова |
| [ |
если значение текущей ячейки нуль, перейти вперёд по тексту программы на ячейку, следующую за соответствующей ] (с учётом вложенности) |
Реализовано. |
| ] |
если значение текущей ячейки не нуль, перейти назад по тексту программы на символ [ (с учётом вложенности) |
Реализовано. |
Что нужно для реализации интерпретатора на нормальных алгоритмах Маркова: строка, в которую будем вводить код на брейнфаке(без оператора "," ), строка выполняющая роль ленту памяти, строка буффера(для вывода результата), строка для вывода результата.
При начале работе интерпретатора строка-лента должна иметь вид
._…
Количество точек — это количество доступных ячеек памяти, символ _ — указатель на текущую ячейку.
Продукции алгорима Маркова будем задавать в виде двух массивов строк одинаковой длины: первый — левые части продукций, второй — правые. Если правая часть продукции заканчивается на FIN, то это значит что эта продукция будет финальной.
Начнем с того, что проще — реализация операций брейнфака алгоритмами Маркова.
| Команда Brainfuck |
Реализация алгоритмом Маркова |
| > |
В строке-ленте:string[] left = new string[5] { "|_.", "@_|", "@_.", "_..", "_.|" }; |
| < |
В строке-ленте:string[] left = new string[2] { "|_", "._" }; |
| + |
В строке-ленте:string[] left = new string[1] { "_"}; |
| - |
В строке-ленте:string[] left = new string[1] { "|_" }; |
| . |
В строке-буффере:| > .a |
| [ |
В строке-исходнике(учитывает влож��нность [])string[] left = new string[10] { "_+", "_-", "_.", "_,", "_<", "_>","_[","_]","**","]*" }; |
| ] |
В строке-исходнике(учитывает вложенность [])string[] left = new string[11] { "+_", "-_", "._", ",_", "<_", ">_", "]_", "[_", "*_","[**", "[*" }; |
Ну и теперь собственно нормальный алгоритм-интерпретатор. Выполняется на строке-исходнике, после каждой продукции вызывается подалгоритм из таблицы операций(см. выше).
| Что заменить | На что заменить | Вызываемый подалгоритм |
| _+ | +_ | + |
| _- | -_ | - |
| _[ | [_ | [ |
| _> | >_ | > |
| _< | <_ | < |
| _] | Если на строке-ленте можно выполнить продукцию ._. на ._.FIN, то ]_ иначе вызов подалгоритма ] |
] |
| _. | ._ | . |
У Вас есть возможность выполнить всю программу сразу или выполнять ее шаг за шагом. Реализация на С#, так что для ее работы нужен установленный .NET 2.0.
Демонстарция работа классического Hello World! на Brainfuck на этом интерпретаторе.

P.S. Надеюсь это было хоть кому-нибудь интересно. Старался уложится �� максимально небольшой объем текста.
Реализация интерпретатора. Можете попробовать этого монстрика в работе.