Para encontrar la dureza digitales de un entero, tome su representación binaria, y contar el número de veces que tanto uno de los principales y de arrastre
1
puede ser retirado hasta que o bien se inicia o termina con una0
. El número total de bits eliminados es su dureza digital.
Esa es una explicación bastante prolija, así que analicemos con un ejemplo trabajado.
Para este ejemplo, usaremos el número 3167. En binario, esto es:
110001011111
(Tenga en cuenta que, durante la conversión a binario, debe asegurarse de eliminar los ceros iniciales)
No comienza ni termina con 0
, por lo que eliminamos 1 par de bits:
1 1000101111 1
Y otro:
11 00010111 11
Pero ahora hay un 0 al principio, por lo que no podemos eliminar más 1
pares. En total, eliminamos 4 bits, por lo que 4 es la dureza digital de 3167.
Sin embargo, para los números que pueden escribirse como 2 n -1 para n positivo (es decir, contener solo 1
en representación binaria), nunca se alcanzará 0, por lo que todos los bits se pueden eliminar. Esto significa que la dureza es simplemente la longitud de bits del entero.
El reto
Su tarea es escribir un programa o función que, dado un número entero no negativo n >= 0
, determine su dureza digital.
Puede enviar un programa completo que realice E / S o una función que devuelva el resultado. Su envío debe funcionar para valores n
dentro del rango entero estándar de su idioma.
Casos de prueba
Notifíqueme si alguno de estos es incorrecto o si desea sugerir algún caso marginal para agregar.
0 -> 0
1 -> 1
8 -> 0
23 -> 2
31 -> 5
103 -> 4
127 -> 7
1877 -> 2
2015 -> 10
Aquí está la solución de Python sin golf que utilicé para generar estos casos de prueba (no se garantiza que no tengan errores):
def hardness(num) -> int:
binary = bin(num)[2:]
if binary.count('0') == 0:
return num.bit_length()
revbin = binary[::-1]
return min(revbin.find('0'), binary.find('0')) * 2
1
devuelve 1 cuando no hay0
en absoluto? Quiero decir, no puedes eliminar suficientes 1 de la cadena para que comience o termine0
.Respuestas:
Jalea ,
1110 bytesPruébalo en línea!
Cómo funciona
fuente
Python ,
76696863626057 bytesPruébalo en línea!
Cómo funciona
Esta es una solución recursiva que toma una entrada ny sigue incrementando k , comenzando en 0 , mientras que LSB k (n) (bit en el índice k desde la derecha) y MSB k (n) (bit en el índice k desde la izquierda) se establecen. Una vez finalizado, devuelve k si todos los bits de n están establecidos y 2k si no.
Comencemos reescribiendo la lambda f como una función con nombre F , con una variable auxiliar t .
En cada invocación de F , primero desplazamos un bit n un total de k unidades a la derecha y almacenamos el resultado en t . De esta manera, LSB 0 (t) = LSB k (n) , entonces t es impar si y solo si LSB k (n) está configurado.
Determinar si MSB k (n) está configurado es un poco más complicado; Esto es lo que se
n & t > t >> 1
logra. Para ilustrar cómo funciona, consideremos un número entero n = 1αβγδεζη 2 de longitud de bit 8 y analicemos la llamada a la función F (n, 3) , es decir, k = 3 .Estamos tratando de determinar si MSB 3 (n) = γ se establece examinando el valor de verdad de la comparación (n & t> t >> 1) = (1αβγδεζη 2 & 1αβγδ 2 > 1αβγ 2 ) . Examinemos los enteros involucrados.
Afirmamos que γ = 1 si y solo si n & t> t >> 1 .
Si γ = 1 , entonces n & t tiene una longitud de bits 5 mientras que t >> 1 tiene una longitud de bits 4 , entonces n & t> t >> 1 .
Esto prueba que γ = 1 implica n & t> t >> 1 .
Si n & t> t >> 1 , hay dos opciones: γ = 1 o γ = 0 . En el primer caso, no queda nada que demostrar.
En el segundo caso, tenemos que αβγδ 2 ≥ n & t> t >> 1 = 1αβγ 2 .
Como αβγδ 2 > 1αβγ 2 , debemos tener MSB 0 (αβγδ 2 ) ≥ MSB 0 (1αβγ 2 ) , lo que significa que α = 1 .
De esta manera, 1βγδ 2 > 11βγ 2 , por lo que debemos tener MSB 1 (1βγδ 2 ) ≥ MSB 1 (11βγ 2 ) , lo que significa que β = 1 .
A su vez, esto implica que 11γδ 2 > 111γ 2 . Recordando que γ = 0 en el segundo caso, obtenemos la desigualdad 110δ 2 > 1110 2 , lo cual es falso ya que MSB 2 (110δ 2 ) = 0 <1 = MSB 2 (1110 2 ) .
Por lo tanto, solo el primer caso es posible y n & t> t >> 1 implica γ = 1 .
En resumen, si ambos LSB k (n) y MSB k (n) se establecen, t será par y n & t> t >> 1 será verdadera , por lo que t & (n & t> t >> 1) se rendimiento 1 . Sin embargo, si LSB k (n) o MSB k (n) está desarmado (o si ambos lo están), t será par o n & t> t >> 1 será Falso , entonces t & (n & t> t> > 1) producirá 0 .
Llamar a F con un solo argumento inicializa k = 0 . Si bien la condición que hemos discutido anteriormente se mantiene, el código posterior
and
se ejecuta, lo que (entre otras cosas) llama recursivamente F con k incrementado .Una vez que LSB k (n) o MSB k (n) se desarma, la condición falla y F (n, k) devuelve 0 . Cada una de las llamadas a funciones k anteriores agrega (n & (n + 1)> 0) + 1 a F (n, k) = 0 , por lo que F (n) devuelve ((n & (n + 1)> 0) + 1) k .
Ahora, si todos los bits de n son iguales (es decir, si n es 0 o todos sus bits están establecidos), n + 1 no tendrá ningún bit en común con n , entonces n & (n + 1) = 0 y F (n) devuelve k . Sin embargo, si n tiene bits establecidos y no establecidos, n & (n + 1)> 0 y F (n) devuelve 2k .
fuente
input()
,,while
yprint
ya son 17 bytes ...MATL ,
1312 bytesPruébalo en línea! O verificar todos los casos de prueba .
Explicación
El código repite cada dígito binario y cuenta cuántas veces es posible eliminar dos dígitos externos.
fuente
Python, 82 bytes
Siento que todavía se puede jugar golf, pero pasé un tiempo probando diferentes métodos y este fue el más corto.
Pruébalo en línea
Aunque esto funciona de manera similar al programa Python del OP, creé esto antes de que se publicara la pregunta, después de ver la pregunta en el Sandbox, que no contenía dicho programa.
fuente
Python 2, 66 bytes
Divide la representación binaria de la entrada en fragmentos de 1. Cuenta el número de 1 en la parte más pequeña de la primera y la última parte, luego la duplica, a menos que haya una sola parte que cuente dos veces.
fuente
PowerShell ,
109106 bytesPruébalo en línea!
Toma de entrada
$args[0]
, utiliza la llamada .NET paraconvert
quetoString
con la base2
(es decir, hacer que sea binario), a continuación,-split
de que la cadena en0
s, tiendas que en$a
. Importante tener en cuenta: la llamada .NET no devuelve ceros a la izquierda, por lo que el primer dígito siempre es un1
.Por lo tanto, hay dos posibilidades: la cadena binaria son todas, o había al menos un cero. Diferenciamos entre aquellos con un pseudoternario indexado por
$a.count-eq1
. Si el binario tiene al menos un cero, el caso de la izquierda, tomamos el mínimo de la longitud de la primera[0]
cadena de1
sy la última[-1]
cadena (encontrada por|sort
y luego[0]
). El más corto de esos es la mayor cantidad de pares que podríamos eliminar, por lo que multiplicamos eso por2
. Tenga en cuenta que si la cadena binaria original termina en a0
, como para input8
, entonces[-1].length
también será0
(ya que es una cadena vacía), que cuando se multiplica por2
sigue siendo0
.De lo contrario, con la cadena binaria todas, tomamos solo
$b
(que previamente se estableció como la longitud de la primera[0]
cadena, en este caso, la totalidad de la cadena binaria).En cualquier situación, ese resultado se deja en la tubería y la salida es implícita.
fuente
JavaScript (ES6), 57 bytes
Toma el binario e intenta hacer coincidir todos
1s
o, en su defecto, un número igual de iniciales y finales1s
.fuente
Retina , 48 bytes
Pruébalo en línea
Explicación:
fuente
C #, 133 bytes
Función que devuelve dureza. Toma entero del argumento.
Bueno, hoy me enteré
'1' + '1' = 98
en C #.fuente
'1'
es el ASCII char 49, y 49 + 49 = 98.1 + 1 = 2
no funcionó. @FlipTackC,
898885 bytesSe guardaron dos bytes debido a que @FlipTack señalaba una declaración inútil.
Llame
f()
con el número para probar, la salida devuelve la función.Pruébalo con ideone .
fuente
JavaScript (ES6),
5958 bytesCasos de prueba
Mostrar fragmento de código
fuente
Jalea , 14 bytes
Pruébalo en línea!
fuente
C,
1371321221191171149894928785 BytesHora de empezar a jugar al golf B-)
Aquí está la prueba
y la salida;
fuente
Java (OpenJDK) ,
181156150 bytesPruébalo en línea!
fuente
Mathematica,
6356 bytesExplicación
Genere la representación de base 2 de la entrada, envuelta con a
List
. Almacenar eso enl
Si el elemento mínimo de
l
es 1, salida 1. Si no, salida 2. Multiplique esto por ...Dividir
l
en carreras.Toma el primer y el último elemento.
Toma el total de ambos.
Encuentra el más pequeño entre los dos.
(Multiplique el primer resultado (1 o 2) con este resultado).
fuente
Octava,
5654 bytesPruébalo en línea!
Explicación:
representación binaria de
n
Tomar min acumulativo
d
y min acumulativo de volteadod
hacer multiplicación de matrices
multiplique por 2 si todos los dígitos son 1;
fuente
Pyth, 18 bytes
Un programa que toma la entrada de un número entero e imprime el resultado.
Conjunto de pruebas (primera línea para formatear)
Cómo funciona
fuente
APL, 26 bytes
Casos de prueba:
Explicación:
fuente
J, 22 bytes
Esto se basa en el ingenioso truco aprendido de este desafío .
Pruébalo en línea!
Explicación
fuente
PHP,
8374 bytes3 + 6 bytes guardados por Jörg
toma entrada de STDIN; correr con
-nR
.Descompostura
fuente
<?=~($s=decbin($argn))[$a=strspn($s,1)]?2*min($a,strspn(strrev($s),1)):$a;
JavaScript (ES6), 83 bytes
Sin golf:
fuente
Mathematica, 62 bytes
Función pura donde
#
representa el primer argumento.(h=0;...;h)&
estableceh=0
, hace un montón de cosas...
, luego regresah
(la dureza). Veamos el montón de cosas:Gracias a Greg Martin por presentarme este truco .
fuente
Haskell ,
9492 bytesPruébalo en línea! Uso:
Explicación:
b
convierte un número a binario y devuelve una lista de cero y unos con el bit menos significativo primero. Enh
, esta lista se invierte y se multiplica por elementos con la lista original, luego sespan(>0)
divide después de la inicial1
s:La tupla resultante coincide con el patrón
(c,_:_)
donde_:_
coincide con cualquier lista no vacía, por lo tantoc = [1,1]
. Debido a que los bytes se eliminan en la parte delantera y trasera,c++c = [1,1,1,1]
se devuelve y finalmente se resume para obtener la dureza digital .Si la segunda lista de tuplas está vacía, entonces la representación binaria solo contiene unos, y el número de unos es la dureza digital. Con la coincidencia de patrones, el error
h
devuelve solon
, lo que nuevamente se resume.fuente
Perl, 61 bytes
El corazón de esto es la expresión regular,
/^(1+).*\1$/
donde 2 veces la longitud$1
es la respuesta. El resto del código está sobrecargado y se ocupa del caso especial de todos los 1.fuente
sprintf
argumentos. Además, el uso de-p
flag le permitirá escribir un programa completo que será más corto que su función, ya que podrá omitirlosub f{...}
(en su lugar, tendrá que terminar$_=...
pero eso sigue siendo una mejora de 4 bytes). Finalmente, en lugar de tulength(...)
, puedes hacerlo/0/&&s/^(1+).*\1$/$1$1/;$_=y///c
. Esto debería llevarte a 51 bytes.PHP, 65 bytes
Versión en línea
fuente
CJam, 14 bytes
Explicación:
fuente