Escriba el código más corto para invertir el orden de bits de un entero de 32 bits.
Reglas:
- Se supone que la entrada es un entero válido o equivalente de cadena si su idioma no admite valores numéricos (por ejemplo, Windows Batch).
- La salida debe ser un entero válido o una cadena equivalente si su idioma no admite valores numéricos (por ejemplo, Windows Batch).
- Biblioteca estándar solamente.
- Puede ser una función o un programa completo.
- La entrada puede ser desde
stdin
o como un argumento de función. - La salida debe ser
stdout
o como un valor devuelto. - Si su idioma tiene una función de biblioteca integrada o estándar que hace esto en un solo paso (por ejemplo,
rbit
en el ensamblaje ARM), eso no se puede usar.
Ejemplos:
Llave:
- decimal
- binario
- (marcha atrás)
- binario invertido
- salida decimal
Ejemplos:
-90
(Ejemplo de 8 bits para demostración)10100110b
- (marcha atrás)
01100101b
101
486
00000000000000000000000111100110b
- (marcha atrás)
01100111100000000000000000000000b
1736441856
-984802906
11000101010011010001100110100110b
- (marcha atrás)
01100101100110001011001010100011b
1704506019
Nota: Las omisiones son juegos gratis. Si no lo dije, y no es una de las lagunas estándar , entonces está completamente permitido.
Respuestas:
Ensamblado x86, 9 bytes
En forma de bytes:
33 C0 40 D1 E9 13 C0 73 FA
9 bytes.fuente
__fastcall
y no tenía elret
.Ensamblado MMIX (28 bytes)
Números de 64 bits
Esto se ensambla para:
¿Como funciona?
La
MOR
instrucción realiza una multiplicación matricial en dos cantidades de 64 bits utilizadas como dos matrices de booleanos 8x8. Un número booleano con dígitos abcdefghklmnopqr 2 se usa como una matriz como esta:La
MOR
instrucción multiplica las matrices representadas por sus argumentos donde la multiplicación esand
y la suma esor
. Es:y además:
que es el orden inverso de los bits del número original.
Números de 32 bits
Si solo desea el reverso de un número de 32 bits en lugar de un número de 64 bits, puede usar este método modificado:
montado:
La primera multiplicación de matrices básicamente funciona así:
el octabyte correspondiente es el
#0000000001020408
que cargamos en las dos primeras instrucciones. La segunda multiplicación se ve así:El octabyte correspondiente es el
#0102040810204080
que creamos de la primera matriz así:La segunda multiplicación es como siempre, el código resultante tiene la misma longitud (28 bytes).
fuente
POLY
instrucción del VAX es básicamente una combinación de multiplicar y agregar con un bucle incorporado. También existen cosas similares en arquitecturas modernas (como x86), pero generalmente no tienen un bucle incorporado para evaluar un polinomio completo a la vez.Conjunto 80386 (
1312 bytes)Como una función en la sintaxis de AT&T usando la convención de llamadas cdecl.
Esta función se ensambla a la siguiente secuencia de bytes:
Desglosado en instrucciones:
Funciona así: en cada una de las 32 iteraciones del bucle, el argumento, que se encuentra en
4(%esp)
, se desplaza a la derecha en una posición. El último bit se desplaza implícitamente al indicador de acarreo. Laadc
instrucción agrega dos valores y agrega el valor del indicador de acarreo al resultado. Si agrega un valor a sí mismo, es decir%eax
, efectivamente lo desplaza a la izquierda en una posición. Esto esadc %eax,%eax
una manera conveniente de desplazarse hacia la izquierda%eax
en una posición mientras se desplaza el contenido de la bandera de acarreo al bit de orden inferior.Repito este proceso 32 veces para que
4(%esp)
se vierta todo el contenido de%eax
. Nunca inicializo explícitamente%eax
ya que sus contenidos anteriores se desplazan durante el ciclo.fuente
C,
635248Versión original:
Versión actualizada (con cambios sugeridos por Allbeert , es1024 y Dennis ):
Nota: Dado que la segunda versión omite la configuración
r=0
, el código supone que anint
es de 32 bits. Si esta suposición es falsa, lo más probable es que la función produzca un resultado incorrecto, dependiendo del estado inicial de lar
entrada a la función.Versión final (con más cambios sugeridos por Dennis y Alchymist ):
Nota: Esto coloca la declaración de las variables de trabajo
r
yi
en la lista de parámetros. Los parámetros son los siguientes:n
es el número que se va a invertir en bits.r
yi
son variables de trabajo que deben pasarse como 0.fuente
int
tipo de función, y también cambiarreturn r
a algo asíi=r
como la mayoría de los compiladores de C tienden a dejar el resultado de la última operación en el registro de retorno. Funcionó en gcc y cl para mí.r(n){...}
r(int n){...}
int
aint r=0,i=32;
menos que los saque del cuerpo de la función.-1 >> 1
es-1
para AS y2**31 - 1
para LS, mientras que-1 / 2
es0
.r
yi
como argumentos? Ahorraría tres bytes más ...Julia 0.2, 33 bytes
Hace lo que parece.
bits
le da la representación de bits (respetando el complemento de dos).parseint
no le importa el complemento de dos, pero devuelve un entero de 32 bits, por lo que el complemento de dos simplemente se maneja por desbordamiento.De acuerdo con los registros de cambios, se agregó la detección de desbordamiento
parseint
en Julia 0.3, por lo que esto podría no funcionar más.fuente
Pitón 2, 50
En general, lo mismo que mi solución Pyth. Tome el mod de entrada 2 ** 32, convierta a binario acolchado de 32 bits, invierta, convierta la picadura binaria de nuevo a decimal e imprima.
fuente
CJam, 15 bytes
Pruébalo en línea.
Se utilizó el comodín "Juego libre": la salida siempre será un entero sin signo.
Casos de prueba
Cómo funciona
fuente
JavaScript (E6) 37
39 40 50Función, entrada de número y devolución de número invertido.
Algoritmo más básico, probablemente se puede jugar más golf con algún truco inteligente.Editar recursión en lugar de bucle
Editar 2 Siguiendo la sugerencia de @bebe en
k*2
lugar dek<<1
Editar 3 Algo que me había perdido en absoluto: es un bucle completo de 32 bits, no es necesario inicializar k. Gracias @FUZxxl
Era
Prueba en la consola FireFox, prueba usando números en OP y algunos números más aleatorios de 16 y 32 bits
Ejemplo de salida de prueba
fuente
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):k
para un solo uso yR=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):k
es reutilizablek<<1
vuelvek*2
y sev>>1
vuelvev/2
. funcionó durante 486. No sé sobre otros casos de pruebax86 ensamblado, 10 bytes
Esto supone entrada en eax, salida en edx. (Además, en la salida eax es cero y CF y ZF están configurados, si a alguien le importa).
En lugar de un contador, se introduce un 1 adicional al principio como marcador de fin de datos
fuente
ret
instrucción de retorno de la función e implementar cdecl (es decir, cambiorcr %eax
arcr 4(%esp)
yrcl %edx
arcl %eax
), que terminan con un byte adicional para elret
y otros dos bytes para la referencia de memoria. Aún así, una buena solución.J (
171513 bytes)Aquí hay una definición explícita para explicar lo que hace:
#: y
representay
como un número base 2 usando tantos lugares como sea necesario.x {. y
toma|x
(magnitud dex
) elementos dey
, desde el frente six
es positivo, desde la parte posterior six
es negativo. Si tomamos más elementos que los presentes, el resultado se rellena con ceros._32 {. #: y
efectivamente almohadillas#: y
a 32 bits.|. y
volteay
, i. invierte el orden de los artículos eny
.#. y
interpretay
como un número de base 2.fuente
Dyalog APL , 10 bytes
2⊥
desde-base-2 de⌽
el reverso⎕
entrada numérica⊤⍨
en el sistema numérico que consiste en32/2
32 bitsTryAPL en línea!
fuente
Python - 89
Python representa números binarios negativos como simplemente
-0b{positive_number}
. Entonces, para lidiar con esto, complemente los números negativos y luego XOR con todos los 1.Después de eso, cree la representación de cadena del número entero basada en el formato
{:032b}
que proporciona la representación de 32 bits del número. Finalmente, invierta la cadena y vuelva a convertirla en un número entero.EDITAR
Gracias a @ Martin Büttner por señalar el problema del complemento a dos. Si
n
termina en un complemento de 1 por dos, la versión invertida sería negativa.Afortunadamente, como se explicó anteriormente, a Python le gustan los números binarios negativos de una manera bastante simple. Afortunadamente, la
int
función de Python permite caracteres de signos opcionales en su primer argumento.Entonces, agregue un signo menos si
n
es extraño para satisfacer el complemento de dos.fuente
['','-'][n%2]
es'-'*(n%2)
.Pyth ,
333222Explicación:
Golfs:
33 -> 32: movido agregar a antes de invertir para guardar una cotización final.
32 -> 22: Se utilizó Q mod 2 ^ 32 en lugar de maquinaria complicada. Combinó ambas cuerdas en una.
Casos de prueba:
fuente
GNU dc, 27 bytes
Salida:
Bash + coreutils, 45 bytes
Salida:
Función C, 89 bytes
La misma idea que /codegolf//a/36289/11259 - usando los trucos de Stanford bit twiddling . No va a ganar el golf, pero de todos modos es interesante:
Salida:
fuente
Función Java, 64 caracteres.
También debería funcionar en C.
fuente
PHP, 46 bytes
Versiones en linea
o
fuente
substr
es innecesario (-12 bytes). Deberías mencionar cómo ejecutarlos.-984802906
?<?=bindec(strrev(sprintf("%064b",$argn<<32)));
JS 115
Bueno, eso no se ve bien en absoluto: D
El método de @Florian F en JS tiene 53 bytes de longitud:
fuente
it may be a function
regla significa que no necesita la alerta o avisoC #
8174Operaciones de bit que probablemente se pueden hacer más cortas en todos los lenguajes de programación.
Básicamente, recorre todas las potencias de 2 hasta un máximo entero + 1 (que se convierte en una potencia de dos) y desde (2,147,483,647 + 1) = 0 puedo recorrer a 0. Desplazar bit de izquierda a derecha para mover el bit al primero posición. El último bit en el lugar 32 va 31 pasos a la derecha, el segundo último va a 30 etc. Así que al usar el operador AND con 1 sabré si es 1 o 0. Si es 1, agregaré el valor i actual al resultado y devolverlo.
fuente
i
cuando lo declara, y guardar un byte eliminandoi++
del bucle for, y en lugar de comparar el resultado de1&...
con 0, puede eliminar la instrucción if por completo y multiplicari
por el resultado que dar|=i*(1&(V>>(31-l++)));
dentro del bucleC # 142
Expandido
fuente
Python - 37
Similar a la solución de @ isaacg.
fuente
C ++, 160
Este no es el más corto, sin embargo, solo usa 24 operaciones.
Tomado del libro Hacker's Delight.
Golfizado:
Sin golf:
fuente
Haskell, 145 - no hay operaciones bit a bit
El giro de bits me parece la antítesis de Haskell, por lo que he evitado el uso de operadores bit a bit. El programa resultante ciertamente no es el concursante más corto, pero pensé que el uso de las matemáticas en lugar de las tonterías era interesante al menos.
Explicación
0
sy1
, el bit menos significativo primero dividiendo repetidamente entre 2 y tomando el resto0
s al final de esta lista0
y1
en un entero suponiendo que el bit más significativo es el primero (repetido doble y agregar).No estoy muy seguro de qué constituye "la biblioteca estándar" en Haskell, así que asumí que Data.Tuple y Data.List estaban bien (son bastante estándar).
Además, la salida es un entero de 32 bits sin signo, ya que cambiar eso me costaría bytes: estoy argumentando esto en "las omisiones son juegos gratis".
fuente
PHP,
4641 bytespruébalos en línea
bit a bit ... más o menos. Corre como tubería con
php -nR '<code>'
.PHP, 46 bytes
una solución bit a bit pura; correr como tubería con
-nR
.PHP,
4759 bytesotro enfoque incorporado; guardar en archivo y ejecutar como tubería con
-F
.fuente
Perl - 60
+1 para la bandera p (avíseme si estoy contando esto mal).
Corre con:
fuente
C ++ 69
fuente
e;i;
? Las declaraciones sin tipo no son un C ++ válido. Para las variables ni siquiera es válida C.int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}
61 bytes :)R, 45
Ejemplos:
Siempre justo por debajo de las respuestas de Python. Esa maldita palabra clave de función.
fuente
Rubí,
4341 bytesdef r(n)(0..31).inject(0){|a,b|a*2+n[b]}end
En Ruby, el uso de la notación de índice de paréntesis (foo [i]) devuelve el bit en el enésimo lugar.
--Editar--
Refactorizar la
inject
funcionalidad reduce un par de bytesdef r(n)z=0;32.times{|i|z=z*2+n[i]};z;end
fuente
Perl5: 46
Nada sofisticado. Desplaza la salida a la izquierda, copia lsb antes de cambiar la fuente a la derecha.
fuente
Clojure,
202156142fuente
Perl (37 + 1)
básicamente un puerto de la solución C por Todd Lehman
perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'
fuente