1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
---
language: brainfuck
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Dmitry Bessonov", "https://github.com/TheDmitry"]
lang: ru-ru
---
Brainfuck (пишется маленькими буквами, кроме начала предложения) - это очень
маленький Тьюринг-полный язык программирования лишь с 8 командами.
```
Любой символ игнорируется кроме "><+-.,[]" (исключая кавычки).
Brainfuck представлен массивом из 30000 ячеек, инициализированных нулями,
и указателем, указывающего на текущую ячейку.
Всего восемь команд:
+ : Увеличивает значение на единицу в текущей ячейке.
- : Уменьшает значение на единицу в текущей ячейке.
> : Смещает указатель данных на следующую ячейку (ячейку справа).
< : Смещает указатель данных на предыдущую ячейку (ячейку слева).
. : Печатает ASCII символ из текущей ячейки (напр. 65 = 'A').
, : Записывает один входной символ в текущую ячейку.
[ : Если значение в текущей ячейке равно нулю, то пропустить все команды
до соответствующей ] . В противном случае, перейти к следующей инструкции.
] : Если значение в текущей ячейке равно нулю, то перейти к следующей инструкции.
В противном случае, вернуться назад к соответствующей [ .
[ и ] образуют цикл while. Очевидно, они должны быть сбалансированы.
Давайте рассмотрим некоторые базовые brainfuck программы.
++++++ [ > ++++++++++ < - ] > +++++ .
Эта программа выводит букву 'A'. Сначала, программа увеличивает значение
ячейки №1 до 6. Ячейка #1 будет использоваться циклом. Затем, программа входит
в цикл ([) и переходит к ячейке №2. Ячейка №2 увеличивается до 10, переходим
назад к ячейке №1 и уменьшаем ячейку №1. Этот цикл проходит 6 раз (ячейка №1
уменьшается до нуля, и с этого места пропускает инструкции до соответствующей ]
и идет дальше).
В этот момент, мы в ячейке №1, которая имеет значение 0, значение ячейки №2
пока 60. Мы переходим на ячейку №2, увеличиваем 5 раз, до значения 65, и затем
выводим значение ячейки №2. Код 65 является символом 'A' в кодировке ASCII,
так что 'A' выводится на терминал.
, [ > + < - ] > .
Данная программа считывает символ из пользовательского ввода и копирует символ
в ячейку №1. Затем мы начинаем цикл. Переходим к ячейке №2, увеличиваем значение
ячейки №2, идем назад к ячейке №1 и уменьшаем значение ячейки №1. Это продолжается
до тех пор пока, ячейка №1 не равна 0, а ячейка №2 сохраняет старое значение
ячейки №1. Мы завершаем цикл на ячейке №1, поэтому переходим в ячейку №2, и
затем выводим символ ASCII.
Также, имейте в виду, что пробелы здесь исключительно для читабельности. Вы можете
легко написать и так:
,[>+<-]>.
Попытайтесь разгадать, что следующая программа делает:
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
Программа принимает два числа на вход и умножает их.
Суть в том, что программа сначала читает два ввода. Затем начинается внешний цикл,
сохраняя ячейку №1. Затем программа перемещается в ячейку №2, и начинается
внутренний цикл с сохранением ячейки №2, увеличивая ячейку №3. Однако появляется
проблема: В конце внутреннего цикла, ячейка №2 равна нулю. В этом случае,
внутренний цикл не будет работать уже в следующий раз. Чтобы решить эту проблему,
мы также увеличим ячейку №4, а затем копируем ячейку №4 в ячейку №2.
Итак, ячейка №3 - результат.
```
Это и есть brainfuck. Не так уж сложно, правда? Забавы ради, вы можете написать
свою собственную brainfuck программу или интерпретатор на другом языке.
Интерпретатор достаточно легко реализовать, но если вы мазохист, попробуйте
написать brainfuck интерпретатор... на языке brainfuck.
|