Дружественная республика натолкнула на идею, которая зацепила до глубны души, как, собственно, и все надуманные и замороченные идеи :)
Применять некуда и незачем, разве что скормить родной группе для написания курсовика по построению трансляторов =:) Фактически, если кого-то посетит непреднамеренный творческий кризис, то можно угощаться.
Настоящий Brainfuck ≤1
Brainfuck, вероятно, это самый безумный язык программирования, который встречается на
свете. Сам язык состоит всего из 8 операторов, которыми можно написать практически любую
программу, которую вы хотите. Для работы вам понадобится: компилятор или интерпретатор
(приводятся в конце статьи - компилятор на ассемблере, интерпретатор Brainfuck-C); ASCII
таблица; вероятно калькулятор :).
Основы
Главная идея Brainfuck - манипулирование памятью. Вам выдается 30.000 массив 1 байтовых
блоков, хотя на самом деле размер массива зависит от компилятора или интерпретатора, но
стандартный размер - 30.000. Внутри этого массива вы можете увеличивать указатель,
значение в ячейке и так далее. Для работы, как я уже говорил, используется 8 операторов:
> = увеличение указателя памяти или смещение право на 1 блок
< = уменьшение или смещение влево на 1 блок
+ = увеличение значения в ячейке памяти, на которую ссылается указатель
- = соответственно уменьшение на единиц
[ = аналог цикла while(cur_block_value != 0)
] = если значение в ячейке на которую указывает указатель не равно нулю, то переход на [
, = аналог getchar(), ввод одного символа
. = аналог putchar(), вывод одного сивола на кончоль
Вводные правил
Любые символы кроме описанных выше игнорируются
Все значения в памяти устанавливаются на 0 в начале работы программы
Циклов может быть сколько угодно, однако каждая [ должна заканчиваться]
И вернемся к нашим баранам. Напишем простую программу:
[-]
Что делается? По идее открывается цикл, уменьшается значение текущей ячейки на 1 и цикл
продолжается до тех пор, пока значение не достигнет 0. Однако так как изначально все
значения в памяти и есть 0, цикл никогда не начнется.
Напишем другую программу:
+++++[-]
На С это аналогично такой программе:
*p=+5;
while(*p != 0){
*p--;
}
В этой программе мы увеличили значение по указателю на 5, потом открыли цикл, который
уменьшал значение до 0.
>>>>++
Очевидно, что сначала мы увеличиваем указатель на 4 и затем два раза увеличиваем значение
на 1 два раза. Разнообразим?
>>>>++<<+>>+
Опять же понятно, что сначала 2 записывается в четвертую ячейку, потом 1 во вторую и
затем еще раз 1 прибавляется к 4.
Давайте напишем программу, которая будет уже выводить нечто в консоль, например любимый
всеми нами "Hello world". Выглядит она так:
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.
+++++++..+++.[-]>++++++++[<++++>-] <.
>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.
Круто? Настоящий Brainfuck... Разберем что происходит. Надо помнить, что мы имеем дело с
кодами ASCII для вывода, так что надо оперировать именно такими кодами.
Первая часть:
>+++++++++[<++++++++>-]<.
Сдвигаемся вправо, оставляя первую ячейку пустой, записываем туда 9, открываем цикл. В
цикле смещаемся влево, записываем туда 8, смещаемся вправо и уменьшаем значение на
единицу.
Цикл идет до тех пор, пока во второй ячейке не станет 0. Не слишком трудные вычисления
покажут, что в конце работы программы в первой ячейки памяти будет 72, во второй 0. Это
код буквы Н, поэтому выводим ее в консоль. Продолжаем для каждого символа и в конце
концов получаем заветные Hello world! Занятно, не правда ли? :)