Descrição da tarefa
Dado um número inteiro, troque seus bits (2k – 1) -th e 2k -th menos significativos para todos os números inteiros k> 0 . Esta é a sequência A057300 no OEIS.
(Supõe-se que o número tenha "infinitos" zeros à esquerda. Na prática, isso significa simplesmente acrescentar um único 0 bit a números de comprimento ímpar.)
Isso é código-golfe , então o código mais curto (em bytes) vence.
Casos de teste
0 -> 0
1 -> 2
9 -> 6
85 -> 170
220 -> 236
1827 -> 2835
47525 -> 30298
unsigned char array_of_bytes[1024]
que funcione da maneira que você espera (por exemplo, seja um campo de bits com 1024 *CHAR_BIT
entradas). Eu imagino que a maioria das respostas que suportam entradas de comprimento arbitrário presumiria queCHAR_BIT
era uniforme, já que a troca de bits entre bytes é complicada. Portanto, você poderia absolutamente exigir umk
tamanho constante, como 256 ou algo razoável para o AES, e idiomas sem tipos inteiros de 256 bits teriam que usar loops. Isso pode fazer SIMD vetores vale a pena considerar uma resposta x86 asm: PRespostas:
Geléia ,
1097 bytesExperimente online! ou verifique todos os casos de teste .
Como funciona
fonte
Python 2, 26 bytes
Truques!
Say
n
tem forma...ghfedcba
em binário. Então, podemos dividi-lo em qualquer outroEm seguida, o resultado de comutação de bits
s
pode ser expresso comos=2*o+e
.Preferimos calcular apenas um de
e
eo
, portanto, expressamoso=n-2*e
e substituímosEntão, agora resta expressar
e
em termos den
. O númeroM=4**n/3
tem forma...10101010101
em binário, que serve como uma máscara para os dígitos ímpares. O expoenten
garante queM
seja longo o suficiente. Tomando o bit a bitand
den/2
e esse valor fornecee
como desejado.Em vez disso, podemos expressar
e
em termos deo
e=(n-o)/2
, o que dás=(n+o*3)/2
, o que economiza um byte, graças a uma otimização do xsot.fonte
n
. No entanto, prefiro a convenção de nomenclatura de bits "ímpar" vs. "par" oposta. O LSB é o bit 0, que é par (mesmo que seja o primeiro bit). Na programação do SIMD, em que as aleatórias geralmente selecionam elementos com um índice, os índices contam de 0; portanto, é normal considerar o elemento baixo como um elemento par. por exemplo[ 3 2 1 0 ]
lambda n:n+(n&4**n/3)*3>>1
f(x){return x+((x&~0U/3)*3)>>1;}
retorna 1 para a entrada 2 .calc
(também conhecido como apcalc), e não na C. Eu pensei que ficaria bem, já que não precisava de truncamento para 32 bits, ou o complemento de dois. Não achei que a expressão parecesse correta, então estava disposta a acreditar nos meus testes errados. Mas de qualquer maneira, estou precisando de um REPL melhor para o desenvolvimento de bithacks. Alguma sugestão? (idealmente linha de comando Linux, comobc -l
oucalc
, mas na verdade expondoint32_t
/uint32_t
ou algo assim, não precisão estendida.)Função C, 38
Correção de bits:
Ideone.
Ou pela diversão:
Função recursiva C, 43
De acordo com a fórmula OEIS ,
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
ou
Ideone.
fonte
CJam,
161413 bytesTeste aqui.
Explicação
fonte
Pitão, 9 bytes
Experimente no Compilador Pyth .
Como funciona
fonte
JavaScript (ES6),
3230 bytesFunciona apenas até 1073741823 devido às limitações de números inteiros do JavaScript.
3836 bytes funcionam até 4294967295:Editar: salvou 2 bytes graças a @ user81655.
51 bytes funcionam até 4503599627370495:
fonte
n<<1
sern*2
?n/2
! Não sei por que não pensei nisso antes.>>>
... o que é isso?>>>
mas faz uma mudança sem sinal.>>>0
basicamente converte em um inteiro não assinado de 32 bits.Função x86 asm: 14 bytes de código de máquina
Versão uint64_t: 24 bytes
Convenção de chamada x86-64 SysV (
x
poledi
), mas esse mesmo código de máquina também funcionará no modo 32 bits. (Onde olea
decodificará comolea eax, [edi + eax*2]
, o que dá resultados idênticos ).0x4f - 0x40
= 14 bytesEsta é a saída do compilador do uso da excelente idéia de máscara única do xnor da maneira oposta. (E terminologia oposta: o bit baixo é o bit 0, que é par, não é ímpar.)
Não encontrei nenhuma melhoria sobre o que o compilador faz. Eu poderia ter escrito como
mov eax, 0x555...
/and eax, edi
, mas esse é o mesmo comprimento.A mesma função para números inteiros de 64 bits leva 24 bytes (veja o link godbolt). Não vejo uma maneira menor que 10 bytes
movabs rax, 0x55...
para gerar a máscara em um registro. (Asdiv
instruções do x86 são desajeitadas, portanto a divisão não assinada de todos por um por três não ajuda.)Eu criei um loop para gerar a máscara em rax, mas são 10 bytes (exatamente o mesmo comprimento que o
mov imm64
).Se soubéssemos que nenhum dos bytes existentes
rax
tem seu bit baixo definido, poderíamos pular o arquivoxor
e isso teria 8 bytes de comprimento.Uma versão anterior desta resposta tinha um loop de 10 bytes usando o
loop
insn, mas tinha um pior tempo de execução de0xFFFFFFFFFFFFFF08
iterações, porque eu apenas o definicl
.fonte
Oásis , 17 bytes (não competitivo)
Experimente online!
Oasis é uma linguagem projetada por Adnan, especializada em seqüências.
Atualmente, esse idioma pode fazer recursão e formulário fechado.
Nós usamos esta fórmula:
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
Especificar o caso base é simples:
3120
no final significa simplesmente issoa(0)=0, a(1)=2, a(2)=1, a(3)=3
.fonte
MATL , 10 bytes
Experimente online!
Versão modificada para gerar os primeiros termos da sequência ( OEIS A057300 ).
Explicação
fonte
zsh, 28 bytes
Recebe a entrada como argumento da linha de comando e sai em STDOUT.
Não é compatível com o Bash porque usa a sintaxe de conversão de base específica do zsh.
fonte
Retina, 70 bytes
Suíte de teste. (Ligeiramente modificado.)
Bem, apenas por diversão: 7 bytes
Toma a base-4 como entrada e as saídas como base-4.
Experimente online!
fonte
05AB1E, 8 bytes
Graças a @Adnan por -5 bytes!
Usa a codificação CP-1252.
Experimente Online!
Explicação:
fonte
1 2‚2 1‚
com12Â
por 8 bytes.4в2‰íJJC
C,
323029 bytesAlgoritmo copiado do comentário do xsot na resposta Python do xnor . Em vez de mascarar nos dois sentidos, mascarar de um lado e combinar.
Isso é compilado da mesma forma que a última versão que eu testei e funciona (para x até x
0x3FFFFFFF
e acima disso, desde que o bit 30 não esteja definido, veja abaixo). No código da máquina, tem o mesmo tamanho da minha resposta asm existente.A versão acima sempre limpa a parte alta do resultado . A melhor versão segura é de 32 bytes:
A versão do Python não tem esse problema, porque o python usa tipos inteiros de precisão arbitrária quando necessário , em vez de truncar para um limite superior fixo.
fonte
>>
era uma precedência tão baixa. Não jogo com frequência suficiente para lembrar exatamente quais são as regras, pois os avisos do compilador que sugerem parênteses em casos perigosos me salvam em código real. : PJavascript (ES6),
113109 bytesEconomizou 4 bytes graças ao Upgoat
Como funciona
fonte
+('0b"+binary_string_here)
vez de `parseInt (..., 2)J, 20 bytes
Uso
Onde
>>
está STDIN e<<
está STDOUT.Ungolfed
Três garfos.
Nota
No intérprete oficial,
^:_1
pode ser substituído porinv
, economizando 1 byte.No entanto, nenhum dos intérpretes online implementa isso.
fonte
C #, 44 bytes
Com base na implementação C
int f(int n)=>n>3?4*f(n/4)+f(n%4):n%2*2+n/2;
Experimente aqui: C # pad
fonte
INTERCAL , 60 bytes
Experimente online!
Funciona para números inteiros de 16 bits, com E / S executada no formato mais natural para INTERCAL: a entrada é uma série de dígitos decimais digitados em um dos vários idiomas naturais ou construídos e a saída é em "números romanos massacrados".
Esse é um daqueles raros desafios em que os operadores binários da INTERCAL podem realmente ser utilizados intuitivamente, pois é o reposicionamento de bits. Selecione ( ) e intercale-os novamente na ordem oposta. Felizmente para a contagem de bytes, embora os operadores da INTERCAL não tenham precedência definida (como o objetivo do idioma é não ter precedentes), o C-INTERCAL no TIO não exige muito agrupamento para essa expressão em particular, custando apenas um byte, pois pode ser abreviado .
~
) pega os bits do seu primeiro argumento correspondente aos do segundo argumento e os coloca à direita com zeros, e mingle ($
) intercala os bits de seus argumentos, de modo que os bits do primeiro argumento sejam mais significativos. Portanto, a solução direta é selecionar os bits alternativos menos significativos (.1~#21845
), selecionar os bits alternativos mais significativos (.1~#43690
'.
!
Com suporte para números inteiros de 32 bits:
INTERCAL , 67 bytes
Experimente online!
Não INTERCAL não permite literais de 32 bits, o que realmente torna este um pouco mais fácil de ler, uma vez que significa as constantes mágicas para selecionar pedaços alternados tem que ser construído por mistura dois literais de 16 bits juntos, onde um é todos os zeros e os outros de todos. (Na verdade, mesmo que houvesse literais de 32 bits, isso ainda seria mais curto.
#0$#65535
Estão dois bytes desativados#1431655765
e o mesmo vale para o outro.) Isso comunica todo o processo de maneira não natural para INTERCAL.Uma abordagem alternativa com o uso desajeitado de sobrecarga de operando :
INTERCAL , 71 bytes
Experimente online!
Isso acaba com a seleção, declarando que
:1
é.2
mesclado.3
, configurando:1
a entrada e, em seguida, produzindo.3
mesclado.2
. Uma vez que:1
foi sobrecarregado como.2$.3
,DO :1 <- :2
valores atribui a.2
e.3
de tal modo que:1
adquire o valor de:2
, o que resulta em.2
contendo os bits mais significativos alternadas a partir de:2
e.3
contendo os bits menos significativos alternadas. Essa seria a menor das duas soluções de 32 bits em quatro bytes sePLEASE WRITE IN :1
pudesse substituirPLEASE WRITE IN :2 DO :1 <- :2
por sobrecarregada:1
, masCALCULATING
acaba sendo necessário para o uso de sobrecarga. Também sinto que pode haver uma maneira mais curta de realizar a sobrecarga do que iniciar o programaDO:1<-:1/.2$.3
, mas como isso é INTERCAL, também sinto que não pode haver.fonte
Mathematica, 44 bytes
A mesma abordagem da minha resposta CJam: converter para base-4, trocar 1s e 2s, converter novamente. Ele também usa o truque de alefhalpha para substituir
FromDigits
por umaFold
operação para salvar um byte.fonte
Na verdade, 16 bytes
Experimente online!
Explicação:
fonte
J, 22 bytes
Abordagem alternativa baseada na manipulação de array em vez do truque da base 4.
Uso
Explicação
fonte
REXX, 88 bytes
fonte