Escreva o código mais curto para reverter a ordem dos bits de um número inteiro de 32 bits.
Regras:
- A entrada é assumida como um número inteiro válido ou equivalente a sequência se o seu idioma não suportar valores numéricos (por exemplo, lote do Windows).
- A saída deve ser um número inteiro válido ou equivalente a sequência se o seu idioma não suportar valores numéricos (por exemplo, lote do Windows).
- Somente biblioteca padrão.
- Pode ser uma função ou um programa completo.
- A entrada pode ser de
stdin
ou como um argumento de função. - A saída deve ser
stdout
ou como um valor retornado. - Se o seu idioma tiver uma função de biblioteca interna ou padrão que faça isso em uma etapa (por exemplo,
rbit
na montagem do ARM), isso não poderá ser usado.
Exemplos:
Chave:
- decimal
- binário
- (marcha ré)
- binário invertido
- saída decimal
Exemplos:
-90
(Exemplo de 8 bits para demonstração)10100110b
- (marcha ré)
01100101b
101
486
00000000000000000000000111100110b
- (marcha ré)
01100111100000000000000000000000b
1736441856
-984802906
11000101010011010001100110100110b
- (marcha ré)
01100101100110001011001010100011b
1704506019
Nota: Omissões são jogos grátis. Se eu não disse isso, e não é uma das brechas padrão , é completamente permitido.
Respostas:
montagem x86, 9 bytes
Em formato de byte:,
33 C0 40 D1 E9 13 C0 73 FA
9 bytes.fonte
__fastcall
e não tinha oret
.Montagem MMIX (28 bytes)
Números de 64 bits
Isso monta para:
Como funciona?
A
MOR
instrução executa uma multiplicação de matrizes em duas quantidades de 64 bits usadas como duas matrizes 8x8 de booleanos. Um número booleano com dígitos abcdefghklmnopqr 2 é usado como uma matriz como esta:A
MOR
instrução multiplica as matrizes representadas por seus argumentos onde está a multiplicaçãoand
e a adiçãoor
. Isto é:e além disso:
que é a ordem inversa dos bits do número original.
Números de 32 bits
Se você deseja apenas o inverso de um número de 32 bits em vez de um número de 64 bits, pode usar este método modificado:
montado:
A primeira multiplicação de matrizes funciona basicamente assim:
o octabyte correspondente é o
#0000000001020408
que carregamos nas duas primeiras instruções. A segunda multiplicação é assim:O octabyte correspondente é o
#0102040810204080
que criamos a partir da primeira matriz como esta:A segunda multiplicação é comercial, como de costume, o código resultante tem o mesmo comprimento (28 bytes).
fonte
POLY
instrução do VAX é basicamente um multiplique e adicione com um loop embutido. Coisas semelhantes também existem em arquiteturas modernas (como x86), mas elas geralmente não têm um loop interno para avaliar um polinômio inteiro de uma só vez.80386 montagem (
1312 bytes)Como uma função na sintaxe da AT&T usando a convenção de chamada cdecl.
Essa função é montada na seguinte sequência de bytes:
Dividido em instruções:
Funciona assim: em cada uma das 32 iterações do loop, o argumento, localizado em
4(%esp)
, é deslocado à direita por uma posição. O último bit é implicitamente deslocado para o sinalizador de transporte. oadc
instrução adiciona dois valores e adiciona o valor do sinalizador de transporte ao resultado. Se você adiciona um valor a si mesmo, ou seja%eax
, efetivamente o desloca para a esquerda em uma posição. Isso éadc %eax,%eax
uma maneira conveniente de mudar para a esquerda%eax
em uma posição enquanto muda o conteúdo da bandeira de transporte para o bit de ordem baixa.Repito esse processo 32 vezes para que todo o conteúdo de
4(%esp)
seja despejado%eax
. Eu nunca inicializo explicitamente,%eax
pois seu conteúdo anterior é deslocado durante o loop.fonte
C,
635248Versão original:
Versão atualizada (com alterações sugeridas por Allbeert , es1024 e Dennis ):
Nota: Como a segunda versão omite a configuração
r=0
, o código está assumindo que umint
é de 32 bits. Se essa suposição for falsa, a função provavelmente produzirá um resultado incorreto, dependendo do estado inicial der
entrada na função.Versão final (com outras alterações sugeridas por Dennis e Alchymist ):
Nota: Isso coloca a declaração das variáveis de trabalho
r
ei
na lista de parâmetros. Os parâmetros são os seguintes:n
é o número a ser revertido em bits.r
ei
são variáveis de trabalho que devem ser passadas como 0.fonte
int
tipo de função e também mudarreturn r
para algo como ai=r
maioria dos compiladores C tende a deixar o resultado da última operação no registro de retorno. Funcionou em gcc e cl para mim.r(n){...}
em vez der(int n){...}
int
emint r=0,i=32;
menos que você movê-los para fora do corpo da função.-1 >> 1
é-1
para AS e2**31 - 1
LS, enquanto-1 / 2
é0
.r
ei
como argumento? Pouparia mais três bytes ...Julia 0.2, 33 bytes
Faz o que parece.
bits
fornece a representação de bits (respeitando o complemento de dois).parseint
não se importa com o complemento de dois, mas retorna um número inteiro de 32 bits; portanto, o complemento de dois é simplesmente tratado pelo estouro.De acordo com os changelogs, a detecção de estouro foi adicionada
parseint
na Julia 0.3, portanto, isso pode não funcionar mais.fonte
Python 2, 50
Em geral, o mesmo que minha solução Pyth. Pegue a entrada mod 2 ** 32, converta em binário acolchoado de 32 bits, inverta, converta a picada binária de volta em decimal e imprima.
fonte
CJam, 15 bytes
Experimente online.
Coringa de "jogo grátis" usado: a saída sempre será um número inteiro sem sinal.
Casos de teste
Como funciona
fonte
JavaScript (E6) 37
39 40 50Função, número de entrada e retorno do número invertido.
Algoritmo mais básico, provavelmente pode ser jogado mais com algum truque inteligente.Editar recursão em vez de loop
Editar 2 Seguindo a sugestão @bebe em
k*2
vez dek<<1
Edit 3 Algo que eu tinha perdido: é um loop completo de 32 bits, sem a necessidade de inicializar k. Obrigado @FUZxxl
isso foi
Teste no console do FireFox, teste usando números no OP e alguns números aleatórios de 16 e 32 bits
Exemplo de saída de teste
fonte
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):k
para uso individual eR=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):k
é reutilizávelk<<1
tornak*2
ev>>1
se tornav/2
. ele trabalhou para 486. Eu não sei sobre outros casos de testex86, 10 bytes
Isso assume entrada em eax, saída em edx. (Além disso, na saída, o eax é zero e CF e ZF são definidos, se alguém se importa).
Em vez de um contador, um 1 adicional é inserido no início como marcador de fim de dados
fonte
ret
instruções para retornar da função e implementar o cdecl (ou seja, alterarrcr %eax
pararcr 4(%esp)
ercl %edx
pararcl %eax
), você terá um byte extra para osret
e outros dois bytes para a referência de memória. Ainda assim, uma boa solução.J (
171513 bytes)Aqui está uma definição explícita para explicar o que faz:
#: y
representay
como um número base 2 usando quantos lugares forem necessários.x {. y
pega|x
(magnitude dex
) itens dey
, da frente, sex
positivo, e de trás, sex
negativo. Se pegarmos mais itens do que o presente, o resultado será preenchido com zeros._32 {. #: y
efetivamente pads#: y
para 32 bits.|. y
viray
, i. inverte a ordem dos itens emy
.#. y
interpretay
como um número de base 2.fonte
Dyalog APL , 10 bytes
2⊥
da base 2 de⌽
o invertido⎕
entrada numérica⊤⍨
no sistema numérico que consiste em32/2
32 bitsTryAPL online!
fonte
Python - 89
Python representa números binários negativos de maneira simples
-0b{positive_number}
. Então, para lidar com isso, complemente números negativos e depois XOR com todos os 1s.Depois disso, crie a representação de seqüência de caracteres do número inteiro com base no formato
{:032b}
que fornece a representação de 32 bits do número. Finalmente, inverta a string e volte a transformá-la em um número inteiro.EDITAR
Agradecemos a @Martin Büttner por apontar a questão do complemento de dois. Se
n
terminar em um 1, por complemento de dois, a versão invertida seria negativa.Felizmente, como explicado acima, o Python gosta de números binários negativos de uma maneira bem simples. Felizmente, a
int
função do Python permite caracteres de sinal opcionais em seu primeiro argumento.Então agora, adicione um sinal de menos se
n
for ímpar para satisfazer o complemento de dois.fonte
['','-'][n%2]
é'-'*(n%2)
.Pitão ,
333222Explicação:
Golfe:
33 -> 32: Movido para adicionar antes de reverter para salvar uma cotação final.
32 -> 22: Q mod 2 ^ 32 usado em vez de máquinas complicadas. Combinou as duas cordas em uma.
Casos de teste:
fonte
GNU dc, 27 bytes
Saída:
Bash + coreutils, 45 bytes
Saída:
Função C, 89 bytes
A mesma idéia que /codegolf//a/36289/11259 - usando os hacks de Stanford . Não vai ganhar o golfe, mas interessante, no entanto:
Saída:
fonte
Função Java, 64 caracteres.
Também deve funcionar em C.
fonte
PHP, 46 bytes
Versões Online
ou
fonte
substr
é desnecessário (-12 bytes). Você deve mencionar como executá-los.-984802906
?<?=bindec(strrev(sprintf("%064b",$argn<<32)));
JS 115
Bem, isso não parece nada bom: D
O método do @Florian F em JS tem 53 bytes:
fonte
it may be a function
regra significa que você não precisa de alerta ou avisoC #
8174Operações de bits que provavelmente podem ser feitas mais curtas em todas as linguagens de programação.
Basicamente, faça um loop através de todas as potências de 2 até um número inteiro máximo + 1 (que se transforma em uma potência de duas) e desde (2.147.483.647 + 1) = 0 Eu posso fazer um loop para 0. Deslocamento de bits Esquerda para a direita para mover o bit para o primeiro posição. O último bit no local 32 vai 31 etapas para a direita, o segundo último vai 30 etc. Portanto, usando o operador AND com 1, saberei se é 1 ou 0. Se for 1, adicionarei o valor atual de i ao resultado e devolver.
fonte
i
quando o declarar e salvar um byte removendoi++
do loop for e, em vez de comparar o resultado de1&...
0, você pode remover a instrução if completamente e multiplicari
pelo resultador|=i*(1&(V>>(31-l++)));
C # 142
Expandido
fonte
Python - 37
Semelhante à solução de @ isaacg.
fonte
C ++, 160
Esta não é a mais curta, no entanto, utiliza apenas 24 operações.
Retirado do livro Hacker's Delight.
Golfe:
Ungolfed:
fonte
Haskell, 145 - sem operações bit a bit
A manipulação de bits me parece a antítese de Haskell, por isso evitei o uso de operadores bit a bit. O programa resultante certamente não é o menor concorrente, mas achei que o uso da matemática, em vez da manipulação de bits, era interessante pelo menos.
Explicação
0
s e1
s, bit menos significativo primeiro dividindo repetidamente por 2 e tomando o restante0
s até o final desta lista0
e1
em um número inteiro, assumindo que o bit mais significativo é o primeiro (duplicado e adicionado repetidamente).Não tenho muita certeza do que constitui "a biblioteca padrão" em Haskell, por isso presumi que Data.Tuple e Data.List estavam OK (eles são bastante padrão).
Além disso, a saída é um sem assinatura inteiro de 32 bits desde a mudança que me custaria bytes: Eu estou discutindo isso em "omissões são jogo livre".
fonte
PHP,
4641 bytesexperimentá-los online
bit a bit ... mais ou menos. Executar como tubo com
php -nR '<code>'
.PHP, 46 bytes
uma solução bit a bit pura; correr como tubo com
-nR
.PHP,
4759 bytesoutra abordagem integrada; salve em arquivo e execute como pipe com
-F
.fonte
Perl - 60
+1 para o sinalizador p (deixe-me saber se estou contando isso errado).
Correr com:
fonte
C ++ 69
fonte
e;i;
? Declarações sem tipo não são um C ++ válido. Para variáveis nem sequer é C. 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
Exemplos:
Sempre apenas evite as respostas em Python. Essa maldita palavra-chave de função.
fonte
Rubi,
4341 bytesdef r(n)(0..31).inject(0){|a,b|a*2+n[b]}end
Em Ruby, o uso da notação de índice de colchete (foo [i]) retorna o bit no enésimo lugar.
--Editar--
A refatoração da
inject
funcionalidade reduz alguns bytesdef r(n)z=0;32.times{|i|z=z*2+n[i]};z;end
fonte
Perl5: 46
Nada chique. Ele muda a saída para a esquerda, copia lsb antes de mudar a fonte para a direita.
fonte
Clojure,
202156142fonte
Perl (37 + 1)
basicamente uma porta da solução C de Todd Lehman
perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'
fonte