Несколько советов здесь:
Константы:
Страница константы Esolangs' имеет чрезвычайно полезный список самых коротких путей для создания ценности конкретных. Я нахожу себя просматривающим эту страницу по крайней мере дважды для каждой программы.
Начало всего:
+++[[<+>>++<-]>]
Это устанавливает ленту в формате 3 * n ^ 2, которая выглядит как
3 6 12 24 48 96 192 128 0 0 '
Почему это так важно?
Давайте спустимся по списку:
- 3 и 6 скучные
- 12: близко к 10 (перевод строки) или 13 (возврат каретки). Может также использоваться для счетчика на 0-9
- 24: близко к 26, количество букв в алфавите
- 48: ASCII для
0
- 96: близко к 97, ASCII для
a
- 196 и 128: 196-128 = 64, близко к 65, ASCII для
A
.
Из этого одного алгоритма мы находимся в начале практически каждой последовательности в диапазоне ASCII, вместе со счетчиком для каждой и новой строкой в легкодоступном месте.
Практический пример:
Печать всех прописных и строчных букв и цифр.
С алгоритмом:
+++[[<+>>++<-]>]<<[-<->]<<<<++[->>+.>+.<<<]<--[>>.+<<-]
Без:
+++++++++++++[->+++++++>++>+++++>++++>+<<<<<]>+++++>[-<+.>>.+<]>>---->---[-<.+>]
Мы тратим большую часть байтов, просто инициализируя ленту во втором примере. Отчасти это компенсируется дополнительными движениями в первом примере, но этот метод явно имеет преимущество.
Пара других интересных алгоритмов в том же духе:
3 * 2 ^ п + 1:
+++[[<+>>++<-]+>]
Tape: 4 7 13 25 49 65 197 129 1 0'
Это смещает значения на 1, что выполняет несколько вещей. 12 делает возврат каретки, 64 - фактическое начало прописного алфавита, а 24 ближе к 26.
2 ^ п:
+[[<+>>++<-]>]
Tape: 1 2 4 8 16 32 64 128
Поскольку 64 подходит для заглавных букв, 32 - это ASCII для пробела, а 128 можно использовать в качестве счетчика для 26 (130/5 = 26). Это может сохранить байты в определенных ситуациях, когда цифры и строчные буквы не нужны.
Выберите реализацию, которая подходит для вопроса:
- Отрицательные ячейки почти всегда полезны, и нет причин избегать их (если это не изменит ваш счет)
- Почти то же самое с обтеканием ячеек, тем более что многие константы используют обтекание.
- Произвольные размеры ячеек полезны для бесконечных математических последовательностей, таких как бесконечное вычисление последовательности Фибоначчи (
+[[-<+>>+>+<<]>]
) или обработка больших / отрицательных чисел. Недостатком является то, что некоторые распространенные методы, такие как [-]
и на [->+<]
которые нельзя положиться, на случай, если число отрицательное.
- EOF как 0, -1 или без изменений. 0 обычно предпочтительнее, так как вы можете перебрать весь ввод без дополнительных проверок. -1 полезно при зацикливании структур массива. Я еще не нашел применение без изменений :(.
Следите за тем, что происходит:
У вас всегда должны быть комментарии о том, где должен находиться указатель относительно данных вокруг него, и убедитесь, что вы знаете диапазон возможных значений каждой ячейки. Это особенно важно, когда вы разбиваете указатель перед циклом, потому что вы захотите объединить две возможности позже.
В любой момент мой код полон комментариев к каждой строке, которая выглядит следующим образом:
*0 *dat a_1 ? 0' !0 0*
or
*0 *dat 0' ap1 0 !0 0*
Некоторый дополнительный совет должен назначить символам специальные значения. В приведенном выше примере, '
где указатель, *
означает повторение в этом направлении, ?
означает ячейку с неизвестным значением, !0
означает ненулевую ячейку, _
является заменой -
и p
заменой +
. or
подразумевает, что лента может выглядеть как любое из представлений и должна обрабатываться как таковая.
Ваша схема символов не обязательно должна быть такой же, как моя (у которой есть несколько недостатков), она просто должна быть последовательной. Это также чрезвычайно полезно при отладке, потому что вы можете запустить его до этой точки и сравнить фактическую ленту с тем, что у вас должно быть, что может указать на потенциальные недостатки в вашем коде.