Фон
Последовательность 1-2-3-Трибоначи
Представьте себе на секунду, что вы можете создать последовательность Фибоначчи, заменив стандартную формулу итерации следующим:
По сути, вместо суммирования двух последних, чтобы получить следующее, вы суммируете последние три. Это основа для последовательности 1-2-3-Tribonacci.
Критерий Брауна
Критерий Брауна гласит, что вы можете представлять любое целочисленное значение в виде суммы членов последовательности при условии, что:
Для всех
n
больше 1,
Что это значит для вызова
Вы можете описать любое положительное целое число как сумму членов последовательности 1-2-3-Tribonacci, образованной следующими начальными условиями:
Это известно как, для каждого значения в этой последовательности, соотношение между терминами никогда не бывает больше 2 (отношение в среднем составляет около 1,839).
Как написать в этой системе численного представления
Допустим, вы используете представление с прямым порядком байтов. Выстроить членов последовательности так:
1 2 3 6 11 20 37 68
Затем вы берете свое число, которое будет представлено (для наших тестов, скажем, оно 63
) и находите значения заданных 1-2-3-Tribonacci, которые в сумме составляют 63 (используя сначала самые большие значения!) . Если число является частью суммы, поставьте 1 под ним, 0, если нет.
1 2 3 6 11 20 37 68
0 0 0 1 0 1 1 0
Вы можете сделать это для любого заданного целого числа - просто убедитесь, что вы сначала используете самые большие значения ниже заданного вами значения!
Определение (наконец)
Напишите программу или функцию, которая будет выполнять следующие действия при условии положительного целочисленного ввода n
(записанного в любой стандартной базе) между 1 и максимальным значением вашего языка:
- Преобразуйте значение в определенное числовое представление 1-2-3-Tribonacci.
- Используя это двоичное представление, и читайте его, как если бы оно было двоичным. Это означает, что цифры остаются прежними, но их значение меняется.
- Возьмите это двоичное число и конвертируйте его в основание исходного числа.
- Выведите или верните этот новый номер.
Однако до тех пор, пока вывод действителен, вам не нужно выполнять следующие шаги. Если вы волшебным образом найдете некую формулу, которая короче (и математически эквивалентна), не стесняйтесь ее использовать.
Примеры
Позвольте функции f
быть функцией, описанной определением, и позвольте []
представлять шаги, предпринятые (как little-endian, хотя это не должно иметь значения) (вам не нужно следовать этому процессу, это просто процесс, описанный):
>>> f(1)
[1]
[1]
[1]
1
>>> f(5)
[5]
[0, 1, 1]
[6]
6
>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104
источник
Ответы:
Javascript
117111 байтСпасибо @theonlygusti за помощь в удалении 5 байтов
Как это устроено
Во-первых, функция генерирует все числа Tribonacci, пока не найдет одно больше, чем вход
Далее производится обратный поиск по списку номеров. Если число меньше, чем вход, оно добавляет 2 ^ (индекс этого числа) к возвращаемому значению и уменьшает ввод на это число.
Наконец, он возвращает результат.
Попробуйте онлайн
источник
a[++i]<x
внутри условия для сохранения байта?x>0
наx
. Сохраните еще 2 байта.Python 2 ,
110102 байта-3 байта благодаря Роду (изящный трюк для приведения логического значения
i
к+i
целочисленному типу, поэтому репр`+i`
работает)Попробуйте онлайн!
источник
'01'[i]
на`+i`
i
это логическое значение, а не int. Редактировать - Ооо+i
, аккуратно.JavaScript (ES6),
9793 байтаЗдесь мы используем
reduce()
рекурсивную функцию. Мы предполагаем, что вывод является 31-битным (это наибольшее количество без знака, с которым JS может легко работать для побитовых операций в любом случае).С точки зрения производительности это явно не очень эффективно.
Для любопытных:
F()
для N + 1reduce()
итераций и N итераций быстро сходится к константе Трибоначи (≈ 1.83929). Поэтому каждый дополнительный бит на выходе стоит примерно вдвое больше времени, чем предыдущий.F()
функция называется хорошей 124 миллиона раз.Тестовое задание
NB. Это может занять 1 или 2 секунды.
Показать фрагмент кода
источник
Mathematica,
7874 байтаLinearRecurrence[{1,1,1},{1,2,3},#]
генерирует список, длина которого равна входу, чисел 1-2-3 трибоначи. ({1,1,1}
Представляет сумму предыдущих трех терминов, в то время как{1,2,3}
являются начальными значениями.) Затем#~NumberDecompose~
находит самый жадный способ записать входные данные в виде суммы элементов списка (это та же самая функция, которая разлагает денежную сумму на кратные доступные валюты, например). Наконец,Fold[#+##&,...]
преобразует результирующий двоичный список в целое число (base-10).Предыдущее представление:
Как это часто бывает (хотя и не выше), эта игра в гольф очень медленная на входах больше 20 или около того, потому что она генерирует (с неоптимизированной рекурсией) список трибов, длина которых является входом; замена финала
#
на более разумную границуRound[2Log@#+1]
приводит к гораздо лучшей производительности.источник
123Tribonacci[]
встроенного?Haskell, 95 байт
Пример использования:
f 63
->104
. Попробуйте онлайн! ,Как это работает:
!
строит последовательность 1-2-3-Tribonacci. Учитывая1
,2
и3
в качестве параметров запуска, мы берем первыеn
элементы последовательности. Тогда мы сгиб правой функции ,#
которая вычитает следующий элементe
изn
и устанавливает бит в возвращаемом значении ,r
еслиe
это необходимо или позволяет битовую неустановленные. Установка бита - это удвоение,r
а добавление1
, оставление неустановленным - просто удвоение.источник
Желе , 31 байт
Попробуйте онлайн!
Я почти уверен, что есть намного более короткий способ достичь этого в желе.
Как?
источник
Perl 6 ,
9391 байт-2 байта благодаря b2gills
Как это устроено
Во-первых, он генерирует последовательность 1-2-3-Tribonacci до первого элемента больше, чем вход:
На основании этого он находит подмножество последовательности, которая складывается со входом:
На основании этого он создает список логических значений, определяющих, является ли каждый элемент последовательности частью суммы:
И, наконец, он интерпретирует этот список значений True = 1, False = 0 как основание 2 и возвращает его как (основание 10) число:
источник
*>$^n
и.sum==$n
. Кроме того, пространство не требуется междуmy
и@f
JavaScript (ES6),
6160 байтВычисляет числа 1-2-3-Tribonacci до тех пор, пока оно не достигнет исходного числа, а затем, когда рекурсия раскручивается, пытается вычесть каждое из них по очереди, удваивая результат по мере продвижения.
Редактировать: 1 байт сохранен благодаря @Arnauld.
источник
n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)
сохранить байт?n<x||
но это![]
просто гений.Пакетный,
151148145 байтовПорт моего JavaScript ответа. Изменить: 3 байта сохранены путем передачи аргументов моей подпрограммы в обратном порядке и еще 3 байта с использованием отдельных
@
s в каждой строке вместо@echo off
.источник
Желе ,
191817 байтПопробуйте онлайн!
Фон
Вместо того, чтобы пытаться преобразовать целое число в основание 1,2,3-Трибоначи, затем из двоичного в целое число, мы сделаем обратное: преобразовать целые числа в двоичное, затем из 1,2,3-основание Трионачи в целое число и вернем самый высокий, который соответствует входу. Это легко сделать.
Мы проиллюстрируем процесс для ввода 63 , в частности этап, на котором проверяется 104 . В двоичном, от самой значимой до наименее значащей цифры, 104 равно
где вторая строка представляет позиционные значения этих цифр.
Мы можем расширить последовательность 1,2,3-Tribonacci вправо, наблюдая, что добавленные цифры соответствуют той же рекурсивной формуле. Для трех цифр это дает
Теперь, чтобы вычислить значение базового числа 1,2,3-Трибоначи, мы можем использовать рекурсивную формулу. Поскольку каждое число является суммой трех чисел справа от него (в таблице выше), мы можем удалить первую цифру и добавить ее к первым трем цифрам оставшегося массива. После 7 шагов, которые равны количеству двоичных цифр в 104 , мы редко оставляем только три цифры.
Теперь, поскольку первая и последняя оставшиеся цифры имеют позиционное значение 0 , результатом является средняя цифра, т. Е. 63 .
Как это устроено
источник
Желе ( вилка ),
1716 байтСохранено 1 байт благодаря @Dennis, который играл в гольф, даже не запустив его.
Это основано на развилке Jelly, где я разочарованно продолжаю работать над реализацией эффективного атома фробениусового решения. Для тех, кто заинтересован, я бы хотел сравниться со скоростью Mathematica,
FrobeniusSolve
и, к счастью, есть объяснение их метода в статье «Внесение изменений и поиск подмены: балансировка ранца» Даниэля Лихтблау.объяснение
источник
ḣ3S;µ¡¶3RṚdzæFṪḄ
работать? У меня не установлена ваша вилка, поэтому я не могу проверить.³
ссылается на первый аргумент.jelly.py
были некоторые другие вещи после этого последнего коммита.постоянный ток ,
110102 байтаНу, кажется , что великие умы действительно думают одинаково. Очевидно, алгоритм, который я придумал, чтобы обойти ограничения, по
dc
совпадению точно такой же, который использовался в ответе @ LliwTelrac. Интересный.Попробуйте онлайн!
источник
Python 2 , 93 байта
Это порт моего желе ответа .
Попробуйте онлайн!
источник
утилиты bash + BSD (OS X и т. д.), 53 байта
утилиты bash + GNU (работает также под BSD), 59 байт
Вход и выход в обоих вышеупомянутых являются двоичными.
Попробуйте версию GNU на TIO. (Пример, связанный с, демонстрирует ввод 111111, который равен 63 в двоичном формате, и вывод 1101000, что составляет 104 в двоичном формате.)
Я не думаю, что TIO предлагает вариант BSD, но если у вас есть Mac, вы можете попробовать их оба там. (59-байтовая программа намного быстрее, чем 53-байтовая программа.)
К сожалению,
seq
его нельзя просто отбросить в решение BSD вместоjot
, так как формат вывода forseq
отличается для выходов выше 999999. (Это становится проблемой для входов около 32, так как 32 ^ 4> 1000000.)Вы можете заменить
jot
выше на,seq -f%.f
чтобы заставить это работать с утилитами GNU, но для тех же 59 байтов, вы можете использовать вышеуказанное решение GNU, которое намного быстрее.источник