Подпоследовательность - это любая последовательность, которую вы можете получить от другой, удалив любое количество символов. Отличительные непустые подпоследовательности 100
являются 0
, 1
, 00
, 10
, 100
. Отличительные непустые подпоследовательностями 1010
являются 0
, 1
, 00
, 01
, 10
, 11
, 010
, 100
, 101
, 110
, 1010
.
Напишите программу или функцию с заданным положительным целым числом n, которая возвращает число различных непустых подпоследовательностей двоичного расширения n .
Пример: так как 4
находится 100
в двоичном, и мы видели, что у него было пять различных непустых подпоследовательностей выше, поэтому f(4) = 5
. Начиная с n = 1 , последовательность начинается:
1, 3, 2, 5, 6, 5, 3, 7, 10, 11, 9, 8, 9, 7, 4, 9, 14, 17, 15, 16, 19, 17, 12
Однако ваша программа должна работать при любом n <2 50 в секунду на любой современной машине. Несколько больших примеров:
f(1099511627775) = 40
f(1099511627776) = 81
f(911188917558917) = 728765543
f(109260951837875) = 447464738
f(43765644099) = 5941674
Ответы:
Python 3 ,
95 байт,83 байта[-12 байт благодаря Mr.XCoder :)]
Попробуйте онлайн!
Примечание по алгоритму. Алгоритм вычисляет приращение в уникальных подпоследовательностях, заданных битом в данной позиции t. Приращение для первого бита всегда равно 1. Затем алгоритм выполняет последовательность битов s (t) и добавляет приращение v [s (t)]. На каждом шаге приращение для дополнения s (t), v [1 - s (t)] обновляется до v [1] + v [0]. Финальное число является суммой всех приращений.
Он должен работать в O (log2 (n)), где n - номер ввода.
источник
JavaScript (ES6),
5351 байтКонтрольные примеры
Показать фрагмент кода
Отформатировано и прокомментировано
Нерекурсивная версия, 63 байта
Сохранено 3 байта благодаря @ThePirateBay
Контрольные примеры
Показать фрагмент кода
источник
map
) переменной flagl
вместо пустого массива.Python 2 , 56 байт
Попробуйте онлайн!
Принимая метод от NofP .
59 байтов итеративно:
Попробуйте онлайн!
источник
Желе , 10 байт
При этом используется улучшение @ XNOR в на @ алгоритме NofP в .
Попробуйте онлайн!
Фон
Пусть (a 1 , ..., a n ) - конечная двоичная последовательность. Для каждого неотрицательного целого числа k ≤ n определите o k как число уникальных подпоследовательностей (a 1 , ..., a k ) , которые либо пусты, либо заканчиваются на 1 , z k как число уникальных подпоследовательностей, которые либо пусто, либо заканчивается 0 .
Ясно, что o 0 = z 0 = 1 , поскольку единственной подпоследовательностью пустой последовательности является пустая последовательность.
Для каждого индекса k общее число подпоследовательностей (a 1 , ..., a k ) равно o k + z k - 1 (вычитание 1 учитывает тот факт, что и o k, и z k считают пустую последовательность). Таким образом, общее число непустых подпоследовательностей составляет o k + z k - 2 . Задача просит вычислить o n + z n - 2 .
Всякий раз, когда k> 0 , мы можем вычислить o k и z k рекурсивно. Есть два случая:
а к = 1
z k = z k-1 , так как (a 1 , ..., a k-1 ) и (a 1 , ..., a k-1 , 1) имеют те же подпоследовательности, которые заканчиваются на 0 .
Для каждой непустой подпоследовательности o k - 1 (a 1 , ..., a k ) , оканчивающейся на 1 , мы можем удалить завершающий 1, чтобы получить одну из o k-1 + z k-1 - 1 подпоследовательность (a 1 , ..., a k-1 ) . И наоборот, добавление 1 к каждой из последних последовательностей o k-1 + z k-1 - 1 приводит к одному из предыдущих последовательностей o k - 1 . Таким образом, o k - 1 = ok-1 + z k-1 - 1 и o k = o k-1 + z k-1 .
а к = 0
Как и в предыдущем случае, мы получаем рекурсивные формулы o k = o k-1 и z k = z k-1 + o k-1 .
Как это устроено
источник
05AB1E , 12 байтов
Попробуйте онлайн! Объяснение: Как указано в других ответах, число подпоследовательностей для двоичной строки
a..y0
, заканчивающейся цифрой 1, совпадает с числом для двоичной строкиa..y
, а число, заканчивающееся символом a,0
является общим числом подпоследовательностей для двоичной строки. строкаa..y
(каждый из которых получает0
суффикс) плюс один для0
себя. В отличие от других ответов я не включаю пустую подпоследовательность, поскольку это сохраняет байт, создающий начальное состояние.источник
Java 8, 97 байт
Порт ответа @xnor на Python 2 , что, в свою очередь, является улучшением ответа @NofP на Python 3 .
Попробуй это здесь.
Может быть, это хорошо, что присутствовал тэг ограниченного времени , потому что у меня изначально было следующее, чтобы перехватить все подпоследовательности:
Попробуй это здесь.
Что также сработало, но заняло слишком много времени для последних трех тестовых случаев. Не говоря уже о том, что он намного длиннее (
208204 байта ).источник
6502 машинный код (C64), 321 байт
Онлайн демо
Демо онлайн с проверкой ошибок (346 байт)
Использование:
sys49152,[n]
напримерsys49152,911188917558917
.Ограничение по времени и контрольные примеры требуют решений для расчета в 64-битных числах, поэтому время доказать, что C64 квалифицируется как « современная машина» »;)
Конечно, для этого нужно немного кода, ОС не предоставляет ничего для целых чисел, более 16-битных. Хромая часть здесь: это еще одна реализация (немного измененная) алгоритма NofP, соответственно. улучшенный вариант xnor . Спасибо за идею;)
объяснение
Вот закомментированный список разборки соответствующей части, выполняющей алгоритм:
Остальное - ввод / вывод и преобразование между строковым и 64-битным целым числом без знака (little-endian) с использованием некоторого алгоритма двойного дублирования. Если вам интересно, вот полный источник сборки для версии с проверкой ошибок - версия «в гольф» находится в ветке «гольф».
источник