Dada la entrada de un entero positivo, genera el número de pasos necesarios para encontrar la entrada a través de una búsqueda binaria que comienza en 1.
Estamos simulando una búsqueda binaria para el entero que se proporcionó como entrada, en la que el buscador simulado puede adivinar repetidamente un entero y saber si es demasiado alto, demasiado bajo o correcto. La estrategia para encontrar el número entero es la siguiente:
Sea n el entero dado como entrada que estamos tratando de encontrar.
Comience con una conjetura de 1. (Para cada conjetura, incremente el número de pasos (independientemente de si fue correcto o no) e inmediatamente deténgase y envíe el número total de pasos si la suposición fue correcta).
Duplique la suposición repetidamente hasta que la suposición sea mayor que n (el número objetivo). (O si es correcto, pero eso ya está cubierto por nuestra regla de conjetura correcta mencionada anteriormente).
Ahora, establezca un límite superior de la primera potencia de 2 que sea mayor que n (es decir, el número que se acaba de adivinar), y establezca un límite inferior de la potencia de 2 directamente debajo de él.
Adivine repetidamente el promedio (redondeado hacia abajo) del límite superior y el límite inferior. Si es demasiado alto, configúrelo como el límite superior. Si es demasiado bajo, configúrelo como el límite inferior. Se garantiza que este procedimiento finalmente dará como resultado una suposición correcta.
Aquí hay un ejemplo, para la entrada de n = 21:
1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
repeated doubling \________________________/
repeated averaging
Como se trata de código golf , el código más corto en bytes ganará.
Aquí están todas las salidas de n = 1 a 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
Y aquí hay algunos casos de prueba más grandes:
1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28
Jalea,
1815109 bytesPruébalo en línea! o verificar los casos de prueba pequeños y los casos de prueba grandes .
Antecedentes
Sea n un número entero positivo ym la potencia más pequeña de 2 que sea mayor o igual o igual que n .
La fase de duplicación toma un paso por cada dígito en la representación binaria de m .
Tome la representación binaria de n , elimine el primer dígito más significativo (siempre 1 ) y todos los ceros finales. La fase de promedio toma un paso por cada dígito restante.
Para evitar calcular m , observamos que, si n <m , el número de dígitos binarios de n es exactamente uno menos que el número de dígitos binarios de m .
Si reemplazamos el primer dígito binario de n con un 0 , invierta el resultado, agregue los dígitos binarios originales y elimine todos los ceros iniciales, luego sucede lo siguiente:
Si n es una potencia de 2 , todos los dígitos de la primera mitad (modificada) se eliminan, dejando solo los dígitos de la representación binaria original de n = m .
Si n no es una potencia de 2 , el dígito en la primera mitad que corresponde al dígito más significativo no se elimina, compensando el hecho de que n tiene un dígito binario menor que m .
Cómo funciona
fuente
’B;Bt0L
(7 bytes) funciona en la última versión de Jelly, utilizando el mismo enfoque que en mi respuesta de Julia .ES6, 38 bytes
Como aluden otras respuestas, puede calcular el número de pasos a partir de las posiciones del primer y último bit.
El número de pasos en la fase de duplicación es
n=33-Math.clz32(x-1)
. Queremos 2ⁿ ≥ x peron=33-Math.clz32(x)
nos da 2ⁿ> x, así que restamos 1 de x para compensar.El número de pasos en la fase de promedio es más fácil, es simple
n=Math.clz32(x&-x)-Math.clz32(x)
.x&-x
es una expresión útil que se evalúa al bit más bajo dex
(como una potencia de 2).fuente
x&-x
funciona Pensé que evaluaría el valor absoluto de x.Pyth,
1513 bytesHe encontrado que el número a calcular es
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].
Pruébalo aquí .
fuente
Julia,
3735 bytesGracias a @AlexA. para guardar 2 bytes!
Esto sigue las observaciones de mi respuesta de Jelly , pero trata de manera diferente los casos extremos.
Si n> 1 , la representación binaria de n - 1 tiene un dígito menos que el de la siguiente potencia de 2 , que se compensa al no eliminar el primer dígito de la representación binaria de n .
Al eliminar todos los ceros de ambos lados , nos ocupamos también del caso de borde 1 .
fuente
Haskell, 82 bytes
Esta es una implementación bastante sencilla en Haskell:
Menos golfizado:
fuente