Una subsecuencia es cualquier secuencia que puede obtener de otra eliminando cualquier cantidad de caracteres. Las distintas subsecuencias no vacío de 100
son 0
, 1
, 00
, 10
, 100
. Las subsecuencias no vacías distintas de 1010
son 0
, 1
, 00
, 01
, 10
, 11
, 010
, 100
, 101
, 110
, 1010
.
Escribir un programa o función que dado un número entero positivo n devuelve el número de subsecuencias distintas no vacías de la expansión binaria de n .
Ejemplo: dado que 4
está 100
en binario, y vimos que tenía cinco subsecuencias distintas no vacías arriba, entonces f(4) = 5
. A partir de n = 1 , comienza la secuencia:
1, 3, 2, 5, 6, 5, 3, 7, 10, 11, 9, 8, 9, 7, 4, 9, 14, 17, 15, 16, 19, 17, 12
Sin embargo, su programa debe funcionar para cualquier n <2 50 en menos de un segundo en cualquier máquina moderna. Algunos grandes ejemplos:
f(1099511627775) = 40
f(1099511627776) = 81
f(911188917558917) = 728765543
f(109260951837875) = 447464738
f(43765644099) = 5941674
Respuestas:
Python 3 ,
95 bytes83 bytes[-12 bytes gracias a Mr.XCoder :)]
Pruébalo en línea!
Una nota sobre el algoritmo. El algoritmo calcula el incremento en subsecuencias únicas dadas por el bit en una posición dada t. El incremento para el primer bit es siempre 1. El algoritmo luego ejecuta la secuencia de bits s (t) y agrega el incremento v [s (t)]. En cada paso, el incremento para el complemento de s (t), v [1 - s (t)] se actualiza a v [1] + v [0]. El número final es la suma de todos los incrementos.
Debe ejecutarse en O (log2 (n)), donde n es el número de entrada.
fuente
JavaScript (ES6),
5351 bytesCasos de prueba
Mostrar fragmento de código
Formateado y comentado
Versión no recursiva, 63 bytes.
Guardado 3 bytes gracias a @ThePirateBay
Casos de prueba
Mostrar fragmento de código
fuente
map
) a la variable de bandera enl
lugar de una matriz vacía.Python 2 , 56 bytes
Pruébalo en línea!
Tomando el método de NofP .
59 bytes iterativamente:
Pruébalo en línea!
fuente
Jalea , 10 bytes
Esto utiliza la mejora de @ xnor en el algoritmo de @ NofP .
Pruébalo en línea!
Antecedentes
Sea (a 1 , ..., a n ) una secuencia binaria finita. Para cada número entero no negativo k ≤ n , defina o k como el número de subsecuencias únicas de (a 1 , ..., a k ) que están vacías o terminan en 1 , z k como el número de subsecuencias únicas que son ya sea vacía o termina en 0 .
Claramente, o 0 = z 0 = 1 , ya que la única subsecuencia de la secuencia vacía es la secuencia vacía.
Para cada índice k , el número total de subsecuencias de (a 1 , ..., a k ) es o k + z k - 1 (restando 1 explica el hecho de que tanto o k y z k recuento de la secuencia de vacío). El número total de subsecuencias no vacías es, por lo tanto, o k + z k - 2 . El desafío pide calcular o n + z n - 2 .
Siempre que k> 0 , podemos calcular o k y z k de forma recursiva. Hay dos casos:
a k = 1
z k = z k-1 , ya que (a 1 , ..., a k-1 ) y (a 1 , ..., a k-1 , 1) tienen las mismas subsecuencias que terminan en 0 .
Para cada una de las subsecuencias no vacías de o k - 1 de (a 1 , ..., a k ) que terminan en 1 , podemos eliminar el 1 posterior para obtener una de las o k-1 + z k-1 - 1 subsecuencias (a 1 , ..., a k-1 ) . Por el contrario, agregar un 1 a cada una de las últimassecuencias o k-1 + z k-1 - 1 da como resultado una de lassecuencias anteriores de o k - 1 . Por lo tanto, o k-1 + z k - 1 = ok-1 - 1 y o k = o k-1 + z k-1 .
una k = 0
De manera similar al caso anterior, obtenemos las fórmulas recursivas o k = o k-1 y z k = z k-1 + o k-1 .
Cómo funciona
fuente
05AB1E , 12 bytes
Pruébalo en línea! Explicación: Como se señaló en las otras respuestas, el número de subsecuencias para una cadena binaria
a..y0
que termina en 1 es el mismo que el número de la cadena binariaa..y
, mientras que el número que termina en a0
es el número total de subsecuencias para el binario cadenaa..y
(que cada uno gana un0
sufijo) más uno para0
sí mismo. A diferencia de las otras respuestas, no incluyo la subsecuencia vacía, ya que esto ahorra un byte que construye el estado inicial.fuente
Java 8, 97 bytes
El puerto de la respuesta Python 2 de @xnor , que a su vez es una mejora de la respuesta Python 3 de @NofP .
Pruébalo aquí
Tal vez sea bueno que la etiqueta de tiempo restringido estuviera presente, porque inicialmente tuve lo siguiente para aplicar fuerza bruta a todas las subsecuencias:
Pruébalo aquí
Lo que también funcionó, pero tomó demasiado tiempo para los últimos tres casos de prueba. Sin mencionar que es mucho más largo (
208204 bytes ).fuente
Código de máquina 6502 (C64), 321 bytes
Demostración en línea
Demostración en línea con comprobación de errores (346 bytes)
Uso:
sys49152,[n]
por ejsys49152,911188917558917
.La restricción de tiempo y los casos de prueba requieren soluciones para calcular en números de 64 bits, por lo que el tiempo para demostrar que el C64 califica como " máquina moderna ";)
Por supuesto, esto necesita bastante código, el sistema operativo no proporciona nada para enteros de más de 16 bits. La parte pobre aquí: es otra implementación (ligeramente modificada) del algoritmo NofP resp. La variante mejorada de xnor . Gracias por la idea;)
Explicación
Aquí hay una lista de desmontaje comentada de la parte relevante que realiza el algoritmo:
El resto es entrada / salida y conversión entre cadena y entero sin signo de 64 bits (little-endian) usando algún algoritmo de doble toque. En caso de que le interese, aquí está toda la fuente de ensamblaje para la versión con verificación de errores : la versión "golfed" está en la rama "golf".
fuente