Давним давно, коли ми ще не народилсь, жив був Алан Тьюрінг. І Алан Тьюрінг придумав машину, і була вона потужна, універсальна. Але настільки незрозуміла, що навіть сам Алан Тьюрінг зробив помилки, коли придумував її.
Тому Урбан Мюллер створив іншу, простішу машину. Яка складається з двох стрічок пам'яті (з комірками по одному байту), двох індексів та 8 команд.
Стрічка пам'яті складається з комірок розміром 1 байт, тобто, з чисел від 0 до 255. При старті програми вся стрічка заповнена нулями. Кількість комірок –- як правило 32768 (але насправді можна і необмежено).
Існує індекс, який вказує на якусь з цих комірок, і може бути переміщений вліво або вправо. Комірка, на яку вказує індекс, називається поточною.
Стрічка програми також складається з комірок розміром 1 байт, але на цей раз з символів по кодуванню ASCII.
Вісім з цих символів є командними, всі інші –- ігноруються.
Також є індекс команди, який вказує на якийсь з символів в стрічці програми. Після обробки символу індекс переміщається до наступної команди в стрічці програми, окрім деяких випадків.
Ось приклад програми, яка виводить hello world:
+
–- додати 1 до поточної комірки пам'яті-
–- відняти 1 у поточній комірці пам'яті>
–- перемістити індекс пам'яті на 1 комірку вправо<
–- перемістити індекс пам'яті на 1 комірку вліво.
–- вивести на екран поточну комірку пам'яті як ASCII символ,
–- ввести з клавіатури в поточну комірку пам'яті символ як код по таблиці ASCII[
–- якщо поточна комірка містить нуль, то перемістити індекс програми до наступного ]
, з врахуванням вкладеності квадратних дужок. Інакше –- йти далі по програмі]
–- якщо поточна комірка містить не нуль, то перемістити індекс програми до попереднього [
, з врахуванням вкладеності квадратних дужок. Інакше –- йти далі по програміПри додаванні/відніманні операція виконується по модулю 256 (тобто, якщо в комірці 255, то команда +
перетворить його в 0).
Щоб перевірити, чи зрозуміла вам ця машина, пройдіть тест.
https://forms.gle/AcxjonqgFtsBxT6e8
Перевіряти роботу можна на сайті https://mitxela.com/other/brainfuck
Напишіть свій інтерпретатор цієї машини. Щоб перевірити його правильність, він повинен:
Ось обфускований код для інтерпретатора brainfuck:
Потрібно
Написати конвертер програми з Brainfuck у еквівалентну програму на Python.
Замірити швидкодію оригінального алгоритму і конвертованого для програми факторіалу http://progopedia.com/example/factorial/18/ за допомогою timeit
Напишіть форматтер для Brainfuck програми. Квадратні дужки формують вкладені цикли, тому їх треба відділяти індентацією. Але якщо всередині дужок не міститься інших циклів, і його довжина менше 5 символів, то не треба розбивати на кілька рядків.
Приклад форматування:
Той факт, що Brainfuck ігнорує некомандні символи (а саме, ігнорує символ коментування #
), можна використати для написання програми, яка буде одночасно виконуватись і в Python, і в Brainfuck.
Наприклад, ми можемо написати так:
Код зліва написаний на Python, код справа –- на Brainfuck.
І хоч цей код запуститься у Python, він не буде працювати як задумано в Brainfuck, бо в Пайтон коді використовуються квадратні дужки, знаки плюс, більше та мінус. Але якщо від них позбутись, то це стане можливо!
Як позбутись від квадратних дужок, крапки, коми, плюса, мінуса та більше?
>
позбутись просто. Python вважає що будь-яке ненульове число –- це True в умовних операторах. Тому
,
можна позбутись таким трюком
[-]
обнуляє будь-яке число, і наступна [
ніколи не запустить код всередині квадратних дужок. Фактично, коментар.Ці трюки дозволяють написати програму, яка буде одночасно коректною Python та Brainfuck програмами. Напишіть алгоритм, який перетворює brainfuck програму у таку подвійну Python/Brainfuck програму.
Виділіть ваш алгоритм цієї машини у бібліотеку brain.py
. Після цього потрібно буде написати 4 варіанти інтерпретатора, всі для різних інтерфейсів:
.onkey())
і виводв текст через методи turtle.write()
. Текст програми потрібно вставляти через буфер обміну (при натисненні якоїсь кнопки).