Como muitos de vocês provavelmente sabem, as memórias de hardware (endereçáveis por bytes) podem ser divididas em duas categorias - little-endian e big-endian . Nas memórias little-endian, os bytes são numerados começando com 0 no extremo menor (menos significativo) e nas big-endian ao contrário.
Curiosidade : esses termos são baseados no livro de Jonathan Swift , Gulliver's Travels, onde o rei liliputiano ordenou que seus cidadãos quebrassem seus ovos no finalzinho (portanto, os pequenos-finalistas) e os rebeldes os quebrariam no final grande.
Como a troca funciona
Suponha que tenhamos um número inteiro não assinado (32 bits) 12648430
na memória, em uma máquina big-endian com a seguinte aparência:
addr: 0 1 2 3
memory: 00 C0 FF EE
Ao inverter a ordem dos bytes, obtemos o número inteiro hexadecimal 0xEEFFC000
que é 4009738240
decimal.
Sua tarefa
Escreva um programa / função que receba um número inteiro de 32 bits não assinado em decimal e produz o número inteiro resultante ao trocar a endianidade conforme descrito acima.
Regras
- A entrada estará sempre na faixa
0
de4294967295
- A saída pode ser impressa em STDOUT (novas linhas / espaços à direita são bons) ou retornada
- Entrada e saída estão em decimal
- O comportamento na entrada inválida é deixado indefinido
Casos de teste
0 -> 0
1 -> 16777216
42 -> 704643072
128 -> 2147483648
12648430 -> 4009738240
16885952 -> 3232235777
704643072 -> 42
3735928559 -> 4022250974
4009738240 -> 12648430
4026531839 -> 4294967279
4294967295 -> 4294967295
42
é dado em decimal, mas tecnicamente é em binário em C, por exemplo. É claro que você pode digitar0x2a
, o que eu queria impedir é aceitar a entrada como uma string"2a"
ou algo parecido.Respostas:
linguagem de máquina x86_32, 3 bytes
Isso é meio trapaceiro. A convenção de chamada do registro Pascal (consulte a Wikipedia ) é um pouco como __fastcall, exceto que passa o primeiro parâmetro em eax, e eax também contém o valor de retorno. Também é a limpeza de chamadas, mas como não usamos a pilha para nada além do ponteiro de retorno, não precisamos fazer nada. Isso nos permite evitar um mov ou xchg e apenas usar bswap diretamente.
fonte
bswap
requer um 80486 ou superior :)linguagem de máquina x86_64 Linux,
54 bytesGraças a @peter ferrie por -1.
Experimente online!
fonte
C (gcc),
20,2917 bytes@ sugestão do hvd.
Experimente online!
Resposta antiga;
incluir deve ser importado.
fonte
Japonês ,
1014 bytesTente
Explicação
Converta o número inteiro de entrada em uma string de base 16 (
sG
), use0
para preencher o início com o comprimento 8 (ùT8
), divida em uma matriz de 2 strings de caracteres (ò
), reverse (w
), junte-se a uma string (¬
) e converta novamente em 10 (nG
).fonte
y
essa, quando uma função é atribuída a uma função, aplica sua transformação normal, executa a função e depois inverte a transformação. Nesse caso, acho que permitiria abreviá-losG_ò w ¬
para 8 bytes. Ou seò
fizesse isso também, poderia sersG_ò2_w
por 7 ...&.
advérbio em J faz isso e às vezes é realmente útil no golfe. A codificação de todas as inversões pode ser entediante.sG_òw...
, não conseguia, para a minha vida, descobrir por que não funcionaria! Eu percebi meu (s) erro (s) eventualmente!Gelatina , 10 bytes
Experimente online!
fonte
d⁹²¤d⁹FUḅ⁹
Python 2 , 44 bytes
Experimente online!
fonte
i*8
e não ai
partir dei=24
.x%256
não são necessárias.APL + WIN 14 bytes
Explicação
fonte
256⊥⌽⎕⊤⍨4⍴256
trabalhar para -1 byte?C # ,
7068 bytesProvavelmente isso não é o ideal.
68:
70:
Experimente online!
fonte
return
expressão e, em seguida, usar a sintaxe do membro com expressão corporal:uint e(uint n)=>((n=n>>16|n<<16)&0xFF00FF00)>>8|(n&0xFF00FF)<<8;
para 64 bytes.0xFF00FF
duas vezes por>>
ing antes&
ing, e então você pode encurtar0xFF00FF
a~0u/257
:uint e(uint n)=>((n=n>>16|n<<16)>>8&~0u/257)|(n&~0u/257)<<8;
para 60. ligação TIOWolfram Language (Mathematica) , 24 bytes
Experimente online!
Inverte a entrada interpretada como um número inteiro na base 256 com 4 dígitos.
fonte
05AB1E ,
1210 bytesExperimente online! Explicação:
fonte
JavaScript (ES6),
4543 bytesfonte
t=0
salva 2 bytes:f=(n,p=t=0)=>t++<4?f(n>>>8,p*256+n%256):p
05AB1E , 9 bytes
Experimente online!
-1 graças a Neil .
Porto da minha resposta Jelly.
fonte
MATL ,
1210 bytesExperimente online! Ou verifique todos os casos de teste .
Explicação
fonte
JavaScript (ES6),
5145 bytesSalvo 6 bytes com a ajuda de @ Neil
Casos de teste
Mostrar snippet de código
fonte
f=(n,p=0,t=4)=>t?f(n/256|0,p*256+n%256,t-1):p
.n=>(n>>>24|n>>8&65280|n<<8&16711680|n<<24)>>>0
J, 16 bytes
Experimente online!
Trabalhando em reduzir a expressão da mão direita. Eu acho que posso economizar alguns bytes, fazendo isso funcionar com uma versão beta J. Juro que vi aqui que você pode terminar um trem com um substantivo em uma nova versão beta ...
Explicação
Converta em 4 dígitos base 256, inverta os dígitos e depois converta novamente em decimal. Basicamente, execute o algoritmo fornecido no OP. Talvez seja a única vez em que é útil que a conversão de base mista de J exija que você especifique o número de dígitos, embora sejam 2 bytes a menos se eu pudesse terminar o trem em um substantivo (em
(#:~4#256)
vez disso).fonte
Excel VBA,
10392 bytesA função de janela imediata VBE anônima que recebe a entrada do intervalo é
[A1]
convertida em hexadecimal, inverte bytes e gera saída para a janela imediata do VBEfonte
Conjunto PPC (32 bits), 8 bytes
Como isso funciona:
Infelizmente, não existem emuladores de montagem de PPC on-line que eu possa encontrar para demonstrar. Desculpe!
fonte
Befunge,
6261 ou 49 bytesExperimente online!
Isso está usando o Befunge padrão no interpretador de referência e, portanto, precisamos levar em consideração o fato de que as células de memória são assinadas em 8 bits e corrigir o possível estouro assinado.
Em implementações com células de memória não assinadas (por exemplo, PyFunge) ou onde o intervalo é maior que 8 bits (por exemplo, FBBI), podemos fugir sem essas verificações, economizando 12 bytes.
Experimente o FBBI online!
Experimente o PyFunge online!
Embora observe que o PyFunge possui uma entrada inteira de processamento de erros, portanto, ao testar no TIO, você precisa seguir o número no campo de entrada com uma quebra de espaço ou linha.
fonte
Oitava , 10 bytes
Experimente online!
Talvez seja a primeira vez que o Octave tenha exatamente a mesma pontuação que seu derivado de golfe, o MATL. Obviamente, nesse caso, é a Octave que possui o built-in, e não o MATL, facilitando muito.
Define um identificador para o built-in
swapbytes
, que aceita qualquer tipo de dados, troca a endianness e gera o resultado. Nesse caso, a entrada é um número inteiro não assinado de 32 bits.fonte
C #,
4436 bytesExperimente online!
Isso foi originalmente baseado na resposta C # do Polynomial , que sugeriu que eu publicasse uma nova resposta com minhas melhorias, mas a abordagem adotada na resposta JavaScript de Arnauld acabou sendo ainda mais curta em C #.
fonte
R , 86 bytes
Eu pensei que já havia uma resposta (ou duas) em R para esta pergunta, mas devo ter me enganado ou eles tiveram os mesmos problemas que eu tive com R não fazendo ints assinados. Esse problema eliminou todos os componentes internos que poderiam ter ajudado. Eu tentei a conversão de 256 bases, mas acabou demorando muito, mas acho que ainda há espaço para alguém mais inteligente do que eu fazer isso. Então eu acabei com o seguinte, que é uma conversão de base 2 trocando a ordem em uma função recursiva.
Experimente online!
fonte
R , 41 bytes
Experimente online!
Verifique todos os casos de teste!
Usa uma conversão de base 256, conforme sugerido pelo MickyT aqui . R não possui números inteiros de 32 bits não assinados, nem números inteiros de 64 bits. Isso nos impede de usar operações bit a bit, mas essa abordagem (e provavelmente a de MickyT) provavelmente ainda é mais curta, pois os operadores bit a bit de R são bastante detalhados.
Utiliza o número 4 desta dica , levando em consideração que nunca estamos obtendo um número tão grande quanto
256^4
.n%/%256^(0:3)%%256
extrai os bytes e%*%
, o produto da matriz, é o produto escalar nessa situação,256^(3:0)
afetando a ordem inversa dos bytes.%*%
retornará um 1x1matrix
contendo o valor endian-invertido.fonte
CP-1610Montagem , 6 DECLEs = 8 bytes
Este código deve ser executado em um Intellivision .
Um código de operação CP-1610 é codificado com um valor de 10 bits, conhecido como 'DECLE'. Essa função tem 6 DECLEs, começando em US $ 480C e terminando em US $ 4811.
O CP-1610 possui registradores de 16 bits, portanto, estamos usando dois deles (R0 e R1) para armazenar um valor de 32 bits.
Despejo de execução
fonte
C # (.NET Core) , 72 + 31 = 103 bytes
Experimente online!
+31 para
using System;using System.Linq;
Eu esperava usar o
Array.Reverse
inline, mas não era (veja a alternativa abaixo).C # (.NET Core) , 87 + 13 = 100 bytes
Experimente online!
+13 para
using System;
Esta solução cuida de @JeppeStigNielsen; removendo a restrição de ter tudo em linha salvo 3 bytes.
fonte
using System.Linq;
, ainda pode ser mais barato usarx=>{var a=BitConverter.GetBytes(x);Array.Reverse(a);return BitConverter.ToUInt32(a,0);}
.REXX , 42 bytes
Experimente online!
Ungolfed:
fonte
Rápido, 28 bytes
fonte
Linguagem de máquina ARM Linux, 8 bytes
Para tentar você mesmo, compile e execute o seguinte em um dispositivo Raspberry Pi ou Android executando o GNUroot
fonte
Perl 5 , 27 bytes
Experimente online!
fonte
Perl 5
-p
, 21 bytesExperimente online!
fonte
K4 , 18 bytes
Solução:
Exemplos:
Explicação:
Como não há entradas não assinadas, a entrada é longa.
Converta em matriz booleana (64 bits), reformule, inverta, obtenha os primeiros 8 bytes e converta novamente em comprimento.
Bônus:
Versão de 19 bytes em OK, que você pode experimentar online!
fonte