Целые числа утомительно представлять в Brain-Flak . Есть 8 операторов:
() Evaluates to 1, but does not push anything on any stack
[] Evaluates to an indeterminate value for the purposes of this question
{} Removes the top of the stack and evaluates to it
<> Switches to or back from the alternate stack and evaluates to zero
(foo) Pushes the value of the expression foo to the stack and evaluates to it
[foo] Evaluates to the negation of foo
{foo} Evaluates the expression foo until the top of the stack is zero
<foo> Evaluates to zero but executes foo anyway
foo
может состоять из нескольких операторов, в этом случае они оцениваются и суммируются. Например, (()())
выталкивает 2
в стек (и оценивает 2
тоже).
Очевидно, что этот (()...())
механизм бесполезен в Code Golf, так как для представления больших чисел требуются n*2+2
байты. Поэтому ваша задача состоит в том, чтобы написать программу или функцию, которые будут выводить как можно меньше байт программы Brain-Flak, которая будет выдавать заданное положительное целое число n
в активный стек. Эта программа не должна делать никаких предположений о существующем содержимом стеков, поэтому она не должна оставлять стеки замененными, добавлять или удалять дополнительные значения из стеков.
Хотя ваша программа или функция должна быть способна возвращать работающую программу Brain-Flak для всех входов от 1 до 1 000 000, победителем будет программа или функция, которая генерирует наименьший набор соответствующих программ Brain-Flak для всех 1061 простых чисел от 1000 до 10000 . Вы должны отметить общий размер ваших выходов для этих 1061 входов как часть вашего представления. Ваша программа или функция может принять целое число и вернуть (цепочку) программу Brain-Flak в любом из обычных приемлемых форматов ввода / вывода. Связи будут разорваны с использованием размера вашей программы или функции.
2n
является4^n catalan(n)
.(()()()...())
. Кроме того, если вы просто используете простые числа, это может упустить некоторые возможности оптимизации для композитов.[]
определен для этого вызова? Мне странно реализовывать 7 из 8 операторов. В любом случае, крутой вызов, для меня большая честь, что кто-то напишет вызов, вдохновленный моим собственным языком![]
в своем ответе.Ответы:
Python 2,
593945924458534584165839458250Хорошо, вот мое решение.
Соответствующая функция есть
push(n)
. Чтобы вызвать его, просто нажмите push на целое число, которое вы хотите представить.объяснение
Основной оптимизацией, выполняемой программой, является умножение жесткого кодирования. Идея умножения жесткого кодирования довольно проста. Вы нажимаете на число, а затем нажмите и нажмите его, чтобы создать новое значение. Например, чтобы умножить на два, вы можете использовать следующий код,
((n){})
где n код, производящий конкретное число. Это работает, потому что оба(n)
и{}
имеют значение n.Эта простая идея может быть сделана более сложной для больших чисел. Возьмем, к примеру, 5 некоторое время назад было обнаружено, что лучший способ умножить на пять был
(((n)){}){}{}
. Этот код делает две копии из n, умножает одну на 4 и добавляет две. Используя ту же стратегию, я делаю каждое умножение на основе двоичного представления числа. Я не буду вдаваться в детали того, как это работает прямо сейчас, но я делаю это, отсекая первое двоичное представление и заменяя 0 на){}
1 и 1 на){}{}
, Затем он проверяет, что n нажимается соответствующее количество раз, и балансирует все скобки. (Если вы хотите узнать, как это делается, вы можете посмотреть мой код). Если вы хотите знать, почему это работает, просто спросите меня в комментарии. Я не думаю, что кто-то на самом деле читает все обновления моего поста, поэтому я оставил объяснение.Когда алгоритм пытается найти жесткий код умножения, он пробует все простые числа чисел. Он игнорирует составные факторы, потому что в какой-то момент составные факторы всегда можно выразить более кратко, как свои основные факторы, неизвестно, так ли это до сих пор.
Другой механизм сохранения байтов - это поиск полиномиального решения. Существуют определенные формы многочленов, которые легко представить с помощью убывающих циклов. Эти многочлены включают, но не ограничиваются ими, многоугольные числа. Эта оптимизация находит многочлены, которые соответствуют форме, и создает код, который их создает.
Выход
вставить бен
источник
n
больше или меньше, чемn+1
if n % 3 == 2:
до конца этой функции на один уровень.Brain-Flak, 64664
Попробуйте онлайн!
Вот мой аннотированный код
объяснение
На данный момент это реализует только два правила:
Если n делится на два, вернуть
(n/2){}
Если n не делится на два, вернуть
n-1()
Он также жестко кодирует все числа меньше 6.
источник
Perl
592225915658460 знаковn()
(11322660 символов)(n){}()
(64664 знака)((n)){}{}
(63610 знаков)((n)()){}{}
(63484 символа) - это новый расчет(n){({}[()])}{}
(60748 символов)n[m]
(62800 знаков)(n){m({}[l])}{}
(58460 знаков) - это новый расчетФормула для этого последнего расчета
n(n/l+1)/2+mn/l
. Я пробовал некоторые другие вычисления, но они больше не помогают для данного вывода. Программа фактически генерирует все значения до 9999, но затем перечисляет заданные простые числа и их общую длину.источник
&try($i * $i, "$numbers[$i]{({})({}[()])}{}");
, которое уменьшается до 58032, когда я также добавляю&try((3 * $i * $i - $i) / 2, "$numbers[$i]{({})({}[()])({})}{}");
(квадратные / пятиугольные числа) - это отсюдаPython,
5913658676 символовФункция игры в гольф Brainflak:
Итерация простого числа:
Выход:
Pastebin
Объяснение:
Мы предварительно заполняем список R представления Brain-flak, вычисляя отдельные целые числа в диапазоне, превышающем необходимый [1, m -1], чтобы определить нашу функцию f . Представления формируются путем взятия самого низкого неиспользуемого представления (индексированного l ) и формирования множества новых представлений из него, оставляя только самое короткое. Самое низкое неиспользуемое представление предполагает, что всем номерам с 1 по 1 было назначено представление, и что эти представления уже использовались для создания новых чисел. Если значение меньше l получает более короткое представление, мы должны вернуться назад и воспроизвести числа, начинающиеся с этой точки. Функция f создает программу, сохраняющую число в стеке путем добавления скобок.
Я не знал ни одного Brainflak, когда начал это, и очень благодарен за ответ Eamon Olive за указание формулы для чисел треугольника. Главным образом я обобщил суммирование и неуклонно проверял суммы и различия. Добавление множества кратных сумм имело большой эффект.
Для тех, кто заботится, вот код, который я использовал, чтобы увидеть, какие формулы стоили того.
Формулы представления:
(X){}
((X)){}{}
((((X)))){}{}{}{}
((((((X)))))){}{}{}{}{}{}
XY
X[Y]
(X){({}[Y])}{}
(X)({({}[Y])}{}){}
(X)(({({}[Y])}{})){}{}
(X)(({({}[Y])}{}){}){}
т. Д.
источник
Луа 5.3, 57522
На самом деле я начал работать над этим, когда вопрос был опубликован, но забыл об этом до годовщины Brain-Flak.
Идея, аналогичная другим ответам, где известные полезные функции используются для построения больших чисел из хороших представлений более простых чисел.
Одно из отличий состоит в том, что вместо решения подзадач с точки зрения меньших чисел я решаю подзадачи с точки зрения чисел с более короткими представлениями. Я думаю, что это делает более элегантным использование отрицательных чисел, а также обработку случая, когда меньшие числа представлены в виде больших чисел.
Кроме того, попытка найти все числа, которые могут быть представлены в определенном размере, а попытка представить конкретное число как можно короче, фактически упрощает некоторые вычисления. Вместо того, чтобы работать с формулой в обратном порядке, чтобы увидеть, может ли она быть применена к числу, формулу можно обработать и применить к каждому числу.
Другое отличие состоит в том, что известные решения хранятся в двух частях - (опционально) «префикс» и «суффикс» (больше похоже на инфикс). Ожидается, что оценка префикса будет игнорироваться при вычислении заданного числа - префикс просто содержит код, который устанавливает суффикс для запуска (обычно путем помещения одной или нескольких вещей в стек). Таким образом, с учетом префикса и суффикса, соответствующее число может быть помещено в стек с помощью
prefix(suffix)
.Это разделение в основном решает ту же проблему, что и
unpack
функция в ответе Wheat Wizard. Вместо того, чтобы переносить код<...>
только для отмены этого позже, такой код просто добавляется к префиксу.В некоторых случаях префикс действительно оценивается (в основном для операции псевдо-возведения в степень), поэтому его оценка также сохраняется. Тем не менее, это на самом деле не вызывает больших проблем, так как генератор не пытается построить конкретные числа. Похоже, теоретически подразумевается, что может быть два фрагмента кода одинаковой длины и генерирование одного и того же числа, которое не будет избыточным в кеше из-за разных значений префикса. Я не стал объяснять это, так как это не имеет большого значения (по крайней мере, в этой области).
Я предполагаю, что было бы легко уменьшить количество байтов, просто добавив больше случаев, но на данный момент у меня достаточно.
Я бежал до 1000000, но только проверял работоспособность до 100000.
Pastebin вывода на заданные простые числа.
источник
k_limit
иk_max_len
делать? Я не уверен, что понимаю заголовок.k_max_len
. Он также мог легко проверить, что он нашел все числа, которые вы запрашивали после обработки каждой длины, но мне было полезно иметь возможность ограничить максимальную длину во время тестирования, чтобы программа работала быстрее. (Обработка больших длин может быть очень медленной.) Вk_limit
основном это входной параметр - он будет выводить программы для чисел до этого - при условии, что ихk_max_len
было достаточно много, чтобы найти их.рубин, 60246 байт
Я использую хэш. Я нахожу лучший гольф для данного числа и использую меньшие, чтобы найти большие.
Рекурсивные хеши - это так весело!
источник
Python, 64014 символов
До этого испытания я ничего не знал о мозговом флаке и только немного повозился с ним на триитонлайне, так что могут быть очевидные сокращения, которые я пропустил. Это довольно скучное решение, просто делит ввод на
x=x/2+x%2
илиx=x/3+x%3
, в зависимости от того, что короче.Назовите это так:
b(42)
вывод на пастин
источник
Lua, 64664 байта
Программа печатает общую длину программ и программы для 203-го простого числа (есть строка, которую вы можете изменить, чтобы изменить, какая из них напечатана, или раскомментируйте строку для печати всех программ)
Прямо сейчас единственная оптимизация - это x = 2 * n + 1
Надеюсь, у меня будет время добавить еще несколько оптимизаций, чтобы снизить оценку.
источник