Ароматный текст
Основанный на стеке esolang Underload имеет некоторые интересные связи с функциональным программированием. Одним из них является обработка числового типа данных - подобно лямбда-исчислению, вы представляете натуральное число N функцией, которая выполняет действие N раз.
Для простоты мы рассмотрим только следующее подмножество команд недогрузки:
:
- Эта команда дублирует верхний элемент в стеке.*
- Эта команда объединяет два верхних элемента в стеке в один элемент.
Определим НЕДОГРУЗКИ цифру N в виде строки :
и *
, при исполнении, потребляйте верхний элемент в стеке, и производят N копий этого элемента объединяются вместе. Несколько примеров:
- Нет цифр недогрузки 0, -1, 1/2, π.
- Пустая строка
является цифрой недогрузки 1, поскольку она не затрагивает стек.
:*
является цифрой недогрузки 2, потому что она дублирует верхний элемент, а затем объединяет эти две копии в один элемент:(A):*
=(A)(A)*
=(AA)
.::**
является цифрой недогрузки 3:(A)::**
=(A)(A):**
=(A)(AA)*
=(AAA)
.:::***
является цифрой недогрузки 4.:*:*
также цифра недогрузки 4:(A):*:*
=(AA):*
=(AA)(AA)*
=(AAAA)
.
В общем, вы обнаружите, что если M
и N
являются числами недогрузки M и N, то :N*
это число N + 1 и MN
это число M × N.
Соревнование
Ваша задача - написать самую короткую программу (с вводом по STDIN) или функцию (с вводом через аргумент), которая генерирует самое короткое представление цифры Underload для его ввода в виде строки. То есть, если вход является положительным натуральным числом N> 1, вы должны создать цифру недогрузки N, длина которой в символах меньше или равна длине любой другой цифры недогружения N.
Образцы входов и выходов: («Вход - OUTPUT
.»)
- 1 -
.
- 2 -
:*
. - 5 -
::*:**
(2 × 2 + 1). - 7 -
::*::***
(2 × 3 + 1) или:::**:**
(3 × 2 + 1). - 33 -
::*:*:*:*:**
(2 × 2 × 2 × 2 × 2 + 1). - 49 -
::*:*:*:*::***
(16 × 3 + 1, длина 14), но не::*::***::*::***
(7 × 7, длина 16).
Если ввод не является положительным натуральным числом, вы можете вернуть ошибку, вызвать неопределенное поведение или даже не завершиться. Объяснение вашего метода поиска ответа приветствуется.
Применяются стандартные ограничения лазейки: никаких дополнительных входных данных, никаких веб-запросов, выходное / возвращаемое значение должно быть именно ответом, а не бесконечным случайным потоком символов :
и *
т. Д.
x
- это то,2*A117498(x)
где A117498 дает оптимальную комбинацию двоичных и факторных методов для нахождения цепочки сложений.Ответы:
GolfScript (
61 60 55 5453 символа)Это менее сложно, чем моя предыдущая версия, и использует немного другой подход, но это все еще грубая сила. Мы знаем, что
':'X*'*'X*+
это подходящее решение, поэтому, если мы сгенерируем все хорошо сбалансированные строки до этой длины и выберем самую короткую, которая оценивает правильную вещь, мы можем быть уверены, что найдем ее.Спасибо Говарду, из решения которого я украл пару твиков с 1 символом.
источник
.&
сразу после внутреннего цикла (то есть между~}%
и}*
.GolfScript (
5453 символа)Это подход, который соответствует духу Говарда (строит строки, которые оценивают правильное значение и выбирает самое короткое, а не грубую силу через строки-кандидаты, чтобы найти те, которые оценивают правильное значение), но достаточно отличается, на мой взгляд это относится к отдельному ответу.
Демонстрационная версия онлайн недоступна, потому что она работает с ошибочной версией переводчика.
источник
3+
с)
(используя тот факт , что[]0=
листы ничего в стеке) , если это не было то , что[]2>
приводит к ошибке.[]2>
дает[]
без ошибок.'1'
.((=
вместо-1=
.Python 2,7 -
878492Пояснение:
Это довольно простое решение. Он рекурсивно проверяет все возможные представления n как произведение двух чисел или как
:(n-1)*
, а затем находит решение с минимальной длиной. диапазон (2, n) необходим для того, чтобы рекурсия имела ограниченную глубину, а n <2 дает базовый случай.Примечания:
i и n / i являются двумя факторами n. ... и ... или ... замена ... если ... еще ... не работает, потому что '' оценивается как ложное. min строк дает одну из самых коротких строк. Python 2.7 сохраняет 1 символ, используя / вместо //.
Редактировать: перенес базовый регистр в конец выражения, что позволило мне использовать ... и ... или ... и сбрить пару пробелов.
Тестовые случаи:
источник
key=len
. Это дает лексикографически раннюю строку. ( Пример ). поскольку'*' < ':'
это означает, что у вас есть склонность к решениям с участием степеней 2, но всегда ли они самые короткие?u(33)
, для которого сортировка лексикографически дает 14 символов,::**::*::*:***
но сортировка по длине дает 12 символов::*:*:*:*:**
GolfScript,
635856 символовКод принимает входные данные в STDIN и печатает результат.
Примеры:
Вы можете проверить свои собственные случаи онлайн .
источник
:x(=
битой. Также +1 за возможность пробежать 49 за разумное количество времени.x,2>{x\%!},
дает все истинные делителиx
,{.v=x@/v=+}/
затем объединяет решения дляd
иx/d
для всех делителейd
.{,}$
сортирует их по длине и0=
берет самые короткие из них (плюс начальный:(x-1)*
регистр).Brachylog 2 , 30 (возможно, в конечном итоге 26) байтов, языковые проблемы постдат
Вот функция, которая работает с текущей реализацией Brachylog 2 (и возвращает список кодов символов, потому что у текущей реализации есть некоторые проблемы с обработкой строк):
Попробуйте онлайн!
Язык все еще очень новый. Вот 26 байт версия программы, которая должна работать в соответствии со спецификацией, но использует некоторые невыполненные функции и, следовательно, еще не действительна, но, возможно, будет в будущем (это также еще менее эффективно):
объяснение
Основная идея довольно проста: мы чередуем разложение числа на (1 или более) факторов (необязательно простые факторы, но факторы 1 не допускаются) и выражение каждого из них как 1 + (представление, полученное из рекурсивного вызов). Это гарантирует поиск во всех возможных представлениях числа Underload числа (мы можем применить этап умножения «два раза подряд», умножив вместе более 2 чисел, и ступень приращения дважды в строке, разделив их с этапом умножения, который умножает вместе только один номер). Нам не нужен явный базовый случай, потому что разложение 1 на простые множители дает нам пустой список, и, таким образом, мы строим его со стадией умножения, которая умножает нулевые числа вместе.
Программа довольно неэффективна, особенно потому, что подсказка о порядке оценки, которую я дал (генерировать ответы от кратчайшего до самого длинного с точки зрения размера конечного результата), хотя и решает «самую короткую» часть вопроса, не так уж велика с точки зрения на самом деле сделать программу быстро (гораздо больше полезный совет - «генерировать только самый короткий ответ на каждой рекурсивной стадии», но это занимает больше байтов…). Кроме того,
ḋp~c×ᵐ
каждый из них может генерировать мультипликативные разделы по несколько раз, заставляя программу выполнять много лишней работы.источник
J - 81 символ
Для потомков это было лучшее, что я мог сделать в J.
Мы создаем список результатов, начиная с двух пустых строк (это
,~
иa:
) и представляющих 0 (никогда не использовался) и 1, а затем перебираем глагол над ними (хитрое использование ловушек, поездов и&
), который добавляет кратчайшее представление следующего числа.Фактический глагол, который мы повторяем, использует длину списка как показатель того, над каким числом мы работаем. Сначала мы разбиваем это число на пары факторов (
#(#~]-:"1<.)@(],.%)2}.i.@#
) и извлекаем каждую пару, извлекая из массива ({~
). Мы превращаем каждую из этих пар (их может быть 0, если число простое) в одну строку (<@;"1
).Затем мы добавляем в этот список запись для предыдущего результата, заключенную в квадратные скобки
:
и*
, и сортируем этот список по length ((/:#&>)
). Наконец, мы берем первый результат из этого list (0{
) и добавляем его в конец базового массива ([,
). Когда цикл завершен итерацией, у нас есть список длины на 2 больше входного, начиная с 0. Так что мы должны вернуть строку, следующую за последней (_2{::
).источник
Желе , 33 байта, языковые проблемы
Попробуйте онлайн!
Простое решение для грубой силы.
объяснение
Основная программа
Основная программа использует вспомогательную функцию для перечисления всех возможных способов получения значения посредством умножения, затем пытается создать значение путем сложения и возвращает кратчайшую возможность. Он также обрабатывает базовый случай (ввод
1
).Вспомогательная функция
Вспомогательная функция пробует все возможные методы выражения ввода в виде умножения двух чисел и взаимно-рекурсивно вызывает основную программу, чтобы получить их кратчайшие представления.
источник
GNU Prolog, 96 байт
Первая строка - это грамматика, которая реализует оценку недогрузки и работает в обратном направлении (на самом деле, она не совсем работает в прямом направлении из-за
A#<B
ограничения; измените ееA#<N
на более медленную программу, которая работает в обоих направлениях). Вторая строка определяет функциональный предикатs
(который является функцией, которая реализована как решение этой программы), которая находит кратчайшую возможную строку, которая оценивается как число, указанное в качестве входных данных (это разочаровывающе многословно для относительно простой задачи, но это пролог для тебя…).Программа должна быть достаточно понятной, учитывая, что это более или менее прямой перевод спецификации в грамматику, а затем в синтаксис Prolog; определение
v
говорит, чтоN
это 1 в пустой строке, илиN
этоA
×B
(сA
меньше, чемB
меньшеN
), и строка является конкатенациейv(A)
иv(B)
, илиN
этоM
+ 1, и строка:
конкатенируется сv(M)
конкатенацией со средством «S имеет некоторую длину» , но указание этого в качестве первой вещи в строке действует как подсказка для реализации Пролога, что она должна сначала проверить самую короткую длину (что означает, что мы получим самую короткую возможную длину для возвращаемого значения).*
. Вторая строка немного тоньше;length(S,_)
источник