Los antiguos griegos tenían estas cosas llamadas números simples y doblemente pares. Un ejemplo de un número par individual es 14. Se puede dividir por 2 una vez, y en ese punto se ha convertido en un número impar (7), después de lo cual ya no es divisible por 2. Un número doblemente par es 20. Se puede dividir por 2 dos veces, y luego se convierte en 5.
Su tarea es escribir una función o programa que tome un número entero como entrada y genere el número de veces que es divisible por 2 como número entero, en la menor cantidad de bytes posible. La entrada será un número entero distinto de cero (cualquier valor positivo o negativo, dentro de los límites de su idioma).
Casos de prueba:
14 -> 1
20 -> 2
94208 -> 12
7 -> 0
-4 -> 2
La respuesta con la menor cantidad de bytes gana.
Consejo: Intenta convertir el número a base 2. Mira lo que te dice.
The input will be a nonzero integer
¿Es necesario editar esto después de su comentario acerca de que cero es una entrada potencial?Respuestas:
Jalea , 4 bytes
En la última versión de Jelly,
ÆEḢ
(3 bytes) funciona.Pruébalo aquí .
fuente
Código de máquina x86_64, 4 bytes
¡La instrucción BSF (bit scan forward) hace exactamente esto !
En el ensamblaje de estilo gcc, esto es:
La entrada se proporciona en el registro EDI y se devuelve en el registro EAX según las convenciones de llamadas c estándar de 64 bits .
Debido a la codificación binaria del complemento a dos, esto funciona para los números -ve y + ve.
Además, a pesar de la documentación que dice "Si el contenido del operando de origen es 0, el contenido del operando de destino no está definido". , Encuentro en mi Ubuntu VM que la salida de
f(0)
es 0.Instrucciones:
evenness.s
y arme congcc -c evenness.s -o evenness.o
evenness-main.c
y compile congcc -c evenness-main.c -o evenness-main.o
:Entonces:
gcc evenness-main.o evenness.o -o evenness
./evenness
@FarazMasroor solicitó más detalles sobre cómo se obtuvo esta respuesta.
Estoy más familiarizado con c que las complejidades del ensamblaje x86, por lo que generalmente uso un compilador para generar código de ensamblaje para mí. Sé por experiencia que las extensiones gcc como
__builtin_ffs()
,__builtin_ctz()
y__builtin_popcount()
típicamente compilan y ensamblan a 1 o 2 instrucciones en x86. Entonces comencé con una función c como:En lugar de usar la compilación gcc regular hasta el código objeto, puede usar la
-S
opción de compilar solo para ensamblar -gcc -S -c evenness.c
. Esto da un archivo de ensamblajeevenness.s
como este:Mucho de esto se puede jugar al golf. En particular, sabemos que la convención de llamada c para funciones con firma es agradable y simple: el parámetro de entrada se pasa en el registro y el valor de retorno se devuelve en el registro. Por lo tanto, podemos extraer la mayoría de las instrucciones: muchas de ellas se preocupan por guardar registros y configurar un nuevo marco de pila. No usamos la pila aquí y solo usamos el registro, por lo que no debemos preocuparnos por otros registros. Esto deja el código de ensamblaje "golfizado":
int f(int n);
EDI
EAX
EAX
Tenga en cuenta que, como señala @zwol, también puede usar una compilación optimizada para lograr un resultado similar. En particular,
-Os
produce exactamente las instrucciones anteriores (con algunas directivas de ensamblador adicionales que no producen ningún código de objeto adicional).Esto ahora se ensambla con
gcc -c evenness.s -o evenness.o
, que luego se puede vincular a un programa de controlador de prueba como se describe anteriormente.Hay varias formas de determinar el código de máquina correspondiente a este ensamblaje. Mi favorito es usar el
disass
comando de desmontaje gdb :Entonces podemos ver que el código de máquina para la
bsf
instrucción es0f bc c7
y pararet
esc3
.fuente
evenness-main.c
con diferentes configuraciones de optimización; para mí se rompe con-O
,-O2
o-O3
.Python, 25 bytes
n & -n
pone a cero cualquier cosa excepto el bit menos significativo, por ejemplo, esto:Estamos interesados en el número de ceros finales, por lo que lo convertimos a una cadena binaria usando
bin
, que será el número anterior"0b10000"
. Como no nos preocupamos por el0b
, ni el1
, restamos 3 de esa longitud de cadenas.fuente
Pyth, 6 bytes
Pruébalo aquí .
fuente
JavaScript (ES6), 18 bytes
4 bytes más cortos que
31-Math.clz32
. Jajafuente
Math.clz32
...JavaScript ES6,
2219 bytesParece que la recursión es la ruta más corta.
fuente
Pyth, 8 bytes
Por ejemplo, la representación binaria de
94208
es:Después de dividirse en
1
sy tomar el último elemento de la matriz resultante, esto se convierte en:Eso es 12 ceros, por lo que es "12-ly even".
Esto funciona porque
x / 2
es esencialmentex >> 1
, es decir, un desplazamiento de bits a la derecha1
. Por lo tanto, un número es divisible por 2 solo cuando el LSB es0
(al igual que un número decimal es divisible por 10 cuando su último dígito es0
).fuente
05AB1E ,
45 bytesAhora admite números negativos. Código:
Pruébalo en línea!
Explicación:
Utiliza la codificación CP-1252.
fuente
Pyth, 6 bytes
Básicamente solo
fuente
MATL , 5 bytes
Esto funciona para todos los enteros.
Pruébalo en línea!
fuente
C, 36 (28) bytes
(No prueba el argumento cero porque se especificó un argumento distinto de cero).
Actualización (en respuesta al comentario) : si permitimos declaraciones de funciones de estilo K&R, entonces podemos tener una versión de 28 bytes:
En este caso, confiamos en el hecho de que el compilador predetermina ambos
n
y el tipo de retorno def
toint
. Sin embargo, este formulario genera una advertencia con C99 y no se compila como código C ++ válido.fuente
int n
->n
sigue siendo un código C válido y corta 4 caracteres.Java 7, 39 o quizás 44 bytes
Yay recursión! Tuve que usar una
!=
comparación en lugar de una comparación más corta para que no se desbordara en la entrada negativa, pero aparte de eso, es bastante sencillo. Si es extraño, envíe un cero. Si es par, agregue uno y vuelva a hacerlo.Hay dos versiones porque en este momento la salida para cero es desconocida. El primero se repetirá hasta que la pila se desborde y no muestre nada, porque 0 es infinitamente par. El segundo escupe un 0 agradable, seguro, pero probablemente no matemáticamente riguroso para la salida.
fuente
JavaScript (ES6),
20 bytes19 bytes.Este es un puerto de la solución Haskell de @nimi a JavaScript. Utiliza las propiedades de "cortocircuito" de las
&&
cuales devuelve su lado izquierdo si es falsey (que en este caso es-0
) o si no devuelve su lado derecho. Para implementarodd x = 0
, por lo tanto, hacemos el lado izquierdo1 - (x % 2)
que burbujea a0
través del&&
, de lo contrario recurrimos a1 + f(x / 2)
.El afeitado de
1 - (x % 2)
as(~x) % 2
se debe a @Neil a continuación, y tiene la extraña propiedad que hace que la función anterior se emita-0
para números impares pequeños. Este valor es una peculiaridad de la decisión de JS de que los enteros son dobles IEEE754; Este sistema tiene un separado+0
y-0
que están especialmente revestidos en JavaScript para ser el===
uno al otro. El~
operador calcula la inversión en bits de enteros con signo de 32 bits para el número, que para números impares pequeños será un número par negativo. (El número positivo,Math.pow(2, 31) + 1
por ejemplo, produce en0
lugar de-0
). La extraña restricción a los enteros con signo de 32 bits no tiene ningún otro efecto; en particular no afecta la corrección.fuente
~x&1
es un byte más corto que1-x%2
.Perl 6,
2318 bytesuso
fuente
Ruby 24 bytes
Mi primer envío de código de golf (¡sí!)
Como llegué aquí :
Primero quería obtener un código que realmente cumpliera con las especificaciones para entender el problema, así que construí el método sin importar el número de bytes:
con este conocimiento, reduje la función a un ciclo while y agregué
$*
(ARGV) como entrada e i como el recuento de cuántas veces se ha reducido a la mitad el número antes de que se vuelva impar.Estaba bastante orgulloso de esto y casi lo presenté antes de que me diera cuenta de que todo esto dividido por dos me pareció un poco binario, ser ingeniero de software pero no tanto científico de la computación, esto no fue lo primero que se me ocurrió.
Así que reuní algunos resultados sobre cómo se veían los valores de entrada en binario:
Noté que el resultado era el número de posiciones a la izquierda que tenemos que recorrer antes de que el número se vuelva impar.
Haciendo algunas manipulaciones de cadena simples, dividí la cadena en la última aparición de 1 y conté la longitud de los ceros restantes:
usando el
("%b" % x)
formato para convertir un número en binario, y String # slice para cortar mi cadena.¡He aprendido algunas cosas sobre el rubí en esta búsqueda y espero tener más campos de golf pronto!
fuente
@wizzwizz4
al comienzo de un comentario para responderme. (¡Esto funciona con todos los nombres de usuario!)J, 6 bytes
Explicación:
fuente
C, 37 bytes
f(int x){return x?x&1?0:1+f(x/2):0;}
Verifique recursivamente el último bit hasta que no sea un 0.fuente
f(int n){return __builtin_ctz(n);}
si está dispuesto a usar extensiones gcc. O incluso#define f __builtin_ctz
int
. Es implícito, al igual que el tipo de retorno.f(n){...}
? GCC no lo compilará. No soy un experto en C, pero una búsqueda rápida revela que tal vez esta característica se eliminó en versiones más recientes de C. ¿Entonces tal vez se compilará con las banderas apropiadas?-ansi
o-gnu99
? Sé que lo tengo para trabajar. Escribí una respuesta de consejos al respecto!Haskell, 28 bytes
Ejemplo de uso:
f 94208
->12
.Si el número es impar, el resultado es
0
, de lo contrario,1
más una llamada recursiva con la mitad del número.fuente
div x 2
? ¿Por qué nox/2
?div
es división entera, división de/
coma flotante.Befunge, 20
La ejecución del código se mueve hacia la derecha y se ajusta al segundo carácter de la primera línea (gracias al final
#
) hasta las2%
salidas1
, lo que hace_
que cambie la dirección hacia la izquierda, luego|
hacia arriba, que se envuelve<
en la segunda fila, que sale y sale. Incrementamos el elemento del segundo al tope de la pila cada vez a través del ciclo, luego dividimos la parte superior por 2.fuente
retina ,
2917Pruébalo en línea!
¡2 bytes guardados gracias a Martin!
Toma entrada unaria. Esto coincide repetidamente con la mayor cantidad de
1
s que puede, de modo que ese número de1
s coincida exactamente con el resto de1
s en el número. Cada vez que hace esto, antepone un;
a la cadena. Al final, contamos el número de;
s en la cadena.Si desea entrada decimal, agregue:
al comienzo del programa.
fuente
Jolf, 6 bytes
Pruébalo aquí!
Más bien simple ... Felicitaciones a ETHProductions por expulsar a Jolf con la versión que realmente debería funcionar.
fuente
PARI / GP, 17 bytes
fuente
6502 lenguaje máquina, 7 bytes
Para encontrar el valor posicional del 1 bit menos significativo del valor distinto de cero en el acumulador, dejando el resultado en el registro X:
Para ejecutar esto en el simulador 6502 en e-tradition.net , agregue un prefijo
A9
seguido de un entero de 8 bits.Esto desmonta a lo siguiente:
Esto es equivalente a la siguiente C, excepto que C debe
int
ser de al menos 16 bits:Lo mismo funciona en un 65816, suponiendo MX = 01 (acumulador de 16 bits, índice de 8 bits), y es equivalente al fragmento C anterior.
fuente
Brachylog ,
2715 bytesExplicación
fuente
CJam, 8 bytes
Leer entero, valor absoluto, factorizar primo, contar dos.
fuente
JavaScript ES6, 36
38bytesGolfed dos bytes gracias a @ETHproductions
Respuesta bastante aburrida, pero hace el trabajo. En realidad, puede ser demasiado similar a otra respuesta, si agrega los cambios sugeridos, eliminaré la mía.
Para ejecutarlo, asígnelo a una variable (
a=>{for...
) ya que es una función anónima, luego llámelo cona(100)
.fuente
b%2==0
se puede cambiar ab%2-1
, yc++
se puede mover dentro de la última parte de lafor
declaración. Creo que esto también funcionaría:b=>eval("for(c=0;b%2-1;b/=2)++c")
b%2-1
=>~b&1
Además, creo que esto falla en la entrada de0
, que se puede solucionar conb&&~b&1
b%2-1
la verificación falla para números impares negativos.ES6, 22 bytes
Devuelve -1 si pasa 0.
fuente
DUP , 20 bytes
Try it here!
Convertido a recursividad, la salida es ahora el número superior en la pila. Uso:
Explicación
fuente
Japt,
95 bytes¡Pruébelo en línea!
La versión anterior debería haber sido de cinco bytes, pero esta realmente funciona.
Cómo funciona
fuente
C,
444038 36 bytes2 bytes de descuento gracias @ JohnWHSmith . 2 bytes de descuento gracias @luserdroog .
Prueba en vivo en ideone .
fuente
!(n%2)
con un poco más~n&1
.=0
. Globales se inicializan de manera implícita a 0.a
, ¿no se garantiza que solo funcione la primera vez que se llama? No sabía que estaba permitido.