Uma subsequência é qualquer sequência que você pode obter de outra excluindo qualquer quantidade de caracteres. As distintas subsequências não vazios de 100
são 0
, 1
, 00
, 10
, 100
. As subsequências não vazios de distintos 1010
são 0
, 1
, 00
, 01
, 10
, 11
, 010
, 100
, 101
, 110
, 1010
.
Escreva um programa ou função que, dado um número inteiro positivo n, retorne o número de subsequências não vazias distintas da expansão binária de n .
Exemplo: como 4
está 100
em binário, e vimos que havia cinco subsequências distintas não vazias acima f(4) = 5
. A partir de n = 1 , a sequência começa:
1, 3, 2, 5, 6, 5, 3, 7, 10, 11, 9, 8, 9, 7, 4, 9, 14, 17, 15, 16, 19, 17, 12
No entanto, seu programa deve funcionar para n <2 50 in em um segundo em qualquer máquina moderna. Alguns grandes exemplos:
f(1099511627775) = 40
f(1099511627776) = 81
f(911188917558917) = 728765543
f(109260951837875) = 447464738
f(43765644099) = 5941674
Respostas:
Python 3 ,
95 bytes83 bytes[-12 bytes graças a Mr.XCoder :)]
Experimente online!
Uma nota sobre o algoritmo. O algoritmo calcula o incremento em subsequências únicas dadas pelo bit em uma determinada posição t. O incremento para o primeiro bit é sempre 1. O algoritmo passa pela sequência dos bits s (t) e adiciona o incremento v [s (t)]. Em cada etapa, o incremento para o complemento de s (t), v [1 - s (t)] é atualizado para v [1] + v [0]. O número final é a soma de todos os incrementos.
Ele deve ser executado em O (log2 (n)), onde n é o número de entrada.
fonte
JavaScript (ES6),
5351 bytesCasos de teste
Mostrar snippet de código
Formatado e comentado
Versão não recursiva, 63 bytes
Guardado 3 bytes graças a @ThePirateBay
Casos de teste
Mostrar snippet de código
fonte
map
) à variável flag eml
vez de uma matriz vazia.Python 2 , 56 bytes
Experimente online!
Tomando o método da NofP .
59 bytes iterativamente:
Experimente online!
fonte
Gelatina , 10 bytes
Isso usa a melhoria do @ xnor no algoritmo do @ NofP .
Experimente online!
fundo
Seja (a 1 , ..., a n ) uma sequência binária finita. Para cada número inteiro não negativo k ≤ n , definir o k medida que o número de subsequências únicas de (um 1 , ..., um k ) que está vazio ou final em 1 , z k medida que o número de subsequências que são únicas vazio ou termina em 0 .
Claramente, o 0 = z 0 = 1 , pois a única subsequência da sequência vazia é a sequência vazia.
Para cada índice k , o número total de subsequências de (a 1 , ..., um k ) é o k + z k - 1 (subtraindo 1 contas para o facto de que tanto o k e z k contagem a sequência de vazio). O número total de subsequências não vazias é, portanto, o k + z k - 2 . O desafio pede para calcular o n + z n - 2 .
Sempre que k> 0 , podemos calcular o k e z k de forma recursiva. Existem dois casos:
a k = 1
z k = z k-1 , uma vez que (a 1 , ..., a k-1 ) e (a 1 , ..., a k-1 , 1) têm as mesmas subsequências que terminam em 0 .
Para cada uma das S k - 1 subsequências não vazios de (a 1 , ..., um k ) que terminam em 1 , que pode remover o arrasto 1 para se obter um do o k-1 + z k-1 - 1 subsequências (a 1 , ..., a k-1 ) . Por outro lado, adicionando-se um 1 para cada um destes o k-1 + z k-1 - 1 sequências resulta em um dos o k - 1 sequências anteriores. Assim, o k - 1 = ok-1 + z k-1 - 1 e o k = o k-1 + z k-1 .
a k = 0
De modo semelhante ao caso anterior, obtém-se as fórmulas recorrentes o k = o k-1 e z k = z k-1 + o k-1 .
Como funciona
fonte
05AB1E , 12 bytes
Experimente online! Explicação: Conforme indicado pelas outras respostas, o número de subsequências para uma cadeia binária
a..y0
que termina em 1 é igual ao número da cadeia bináriaa..y
, enquanto o número que termina em a0
é o número total de subsequências para a binária stringa..y
(cada qual obtém um0
sufixo) mais uma para0
si. Diferentemente das outras respostas, não incluo a subsequência vazia, pois isso salva um byte na construção do estado inicial.fonte
Java 8, 97 bytes
Porta da resposta Python 2 do @xnor , que por sua vez é uma melhoria da resposta Python 3 do @NofP .
Experimente aqui.
Talvez seja bom que a tag de tempo restrito estivesse presente, porque inicialmente eu tinha o seguinte para forçar bruteforce todas as subsequências:
Experimente aqui.
O que também funcionou, mas levou muito tempo para os últimos três casos de teste. Sem mencionar que é muito mais longo (
208204 bytes ).fonte
Código da máquina 6502 (C64), 321 bytes
Demonstração online
Demonstração online com verificação de erros (346 bytes)
Uso:
sys49152,[n]
por exemplosys49152,911188917558917
.A restrição de tempo e os casos de teste exigem soluções para serem calculados em números de 64 bits, portanto, o tempo para provar que o C64 se qualifica como " máquina moderna ";)
Obviamente, isso precisa de um pouco de código, o sistema operacional não fornece nada para números inteiros maiores que 16 bits. A parte lame aqui: é mais uma implementação (levemente modificada) do algoritmo da NofP resp. Variante aprimorada do xnor . Obrigado pela ideia;)
Explicação
Aqui está uma lista de desmontagem comentada da parte relevante que está executando o algoritmo:
O restante é entrada / saída e conversão entre string e número inteiro não assinado de 64 bits (little-endian) usando algum algoritmo de duplo toque. Caso você esteja interessado, aqui está toda a fonte de montagem da versão com verificação de erros - a versão "golfed" está na ramificação "golf".
fonte