Dada a entrada de um número inteiro positivo, imprima o número de etapas necessárias para encontrar a entrada por meio de uma pesquisa binária iniciando em 1.
Estamos simulando uma pesquisa binária do número inteiro que foi dado como entrada, na qual o pesquisador simulado pode adivinhar repetidamente um número inteiro e saber se ele é muito alto, muito baixo ou correto. A estratégia para encontrar o número inteiro é a seguinte:
Seja n o número inteiro dado como entrada que estamos tentando encontrar.
Comece com um palpite de 1. (Para cada palpite, aumente o número de etapas (independentemente de estar ou não correto) e pare imediatamente e emita o número total de etapas, se a palpite estiver correta.
Duplique o palpite repetidamente até que o palpite seja maior que n (o número de destino). (Ou se estiver correto, mas isso já está coberto pela nossa regra de palpite correta mencionada acima.)
Agora, defina um limite superior da primeira potência de 2 maior que n (ou seja, o número que foi adivinhado) e defina um limite inferior da potência de 2 diretamente abaixo dela.
Adivinhe repetidamente a média (arredondada para baixo) do limite superior e do limite inferior. Se estiver muito alto, defina-o como o limite superior. Se estiver muito baixo, defina-o como o limite inferior. Este procedimento é garantido para eventualmente resultar em uma estimativa correta.
Aqui está um exemplo, para a entrada de n = 21:
1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
repeated doubling \________________________/
repeated averaging
Como esse é o código-golfe , o código mais curto em bytes será vencedor.
Aqui estão todas as saídas de n = 1 para n = 100:
1
2
4
3
6
5
6
4
8
7
8
6
8
7
8
5
10
9
10
8
10
9
10
7
10
9
10
8
10
9
10
6
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
8
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
7
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
10
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
9
14
13
14
12
E aqui estão alguns casos de teste maiores:
1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28
Geléia,
1815109 bytesExperimente online! ou verifique os casos de teste pequenos e grandes .
fundo
Seja n um número inteiro positivo e m a menor potência de 2 maior ou igual a ou igual a n .
A fase de duplicação dá um passo para cada dígito na representação binária de m .
Pegue a representação binária de n , remova o primeiro dígito mais significativo (sempre 1 ) e todos os zeros à direita. A fase de média dá um passo para cada dígito restante.
Para evitar o cálculo de m , observamos que, se n <m , o número de dígitos binários de n é exatamente um a menos que o número de dígitos binários de m .
Se substituirmos o primeiro dígito binário de n por 0 , inverta o resultado, acrescente os dígitos binários originais e remova todos os zeros à esquerda, e acontece o seguinte:
Se n for uma potência de 2 , todos os dígitos da primeira metade (modificada) serão removidos, deixando apenas os dígitos da representação binária original de n = m .
Se n não for uma potência de 2 , o dígito na primeira metade que corresponder ao dígito mais significativo não será removido, compensando o fato de que n tem um dígito binário menor que m .
Como funciona
fonte
’B;Bt0L
(7 bytes) funciona na versão mais recente do Jelly, usando a mesma abordagem da minha resposta de Julia .ES6, 38 bytes
Conforme mencionado por outras respostas, você pode calcular o número de etapas a partir das posições do primeiro e do último bits.
O número de etapas na fase de duplicação é
n=33-Math.clz32(x-1)
. Queremos 2ⁿ ≥ x, masn=33-Math.clz32(x)
nos dá 2ⁿ> x, então subtraímos 1 de x para compensar.O número de etapas na fase média é mais fácil, é simples
n=Math.clz32(x&-x)-Math.clz32(x)
.x&-x
é uma expressão útil que avalia o bit mais baixo dex
(como uma potência de 2).fonte
x&-x
funciona? Eu teria pensado que avaliaria o valor absoluto de x.Pitão,
1513 bytesEu descobri que o número a ser calculado é
1 + 2*ceil(log_2(x)) - [number of 2s in x's prime factorization, minus 1 if x is a power of 2 greater than 1].
Experimente aqui .
fonte
Julia,
3735 bytesGraças a @AlexA. para economizar 2 bytes!
Isto segue as observações da minha resposta Jelly , mas lida de maneira diferente com os casos extremos.
Se n> 1 , a representação binária de n - 1 tem um dígito a menos que o da próxima potência de 2 , que é compensada por não remover o primeiro dígito da representação binária de n .
Removendo todos os zeros de ambos os lados , lidamos também com o caso 1 da aresta .
fonte
Haskell, 82 bytes
Esta é uma implementação bastante direta no Haskell:
Menos golfe:
fonte