Saída de números de base imaginário-quarto em binário

17

Escreva uma função ou programa que emita a base imaginária do quarto exibida como dígitos binários. A base numérica é 2 i , onde i é a raiz quadrada de -1. Consulte Número complexo para obter mais detalhes sobre i . Cada posição de dígito pode ir de 0 a 3 (quaternário), pois cada parte real e imaginária é -4 vezes maior que a parte real e imaginária anterior. Os dígitos quaternários em binário são as seguintes: 0: 00, 1: 01, 2: 10e 3: 11.

Repartição das posições dos dígitos:

re   im       16 -8i  -4  2i   1 -0.5i, etc.
 4    0        1   0   3   0   0        (quaternary representation)
              01  00  11  00  00        (binary representation)

O número 100110000é 1x16 + 3x-4 = 16 + -12 = 4.

re   im       16 -8i  -4  2i   1 -0.5i, etc.
 0    5        0   0   0   3   0   2    (quaternary representation)
              00  00  00  11  00 .10    (binary representation)

O número 1100.1é 3x2 i + 2x-0,5 i = 6 i + - i = 5 i .

Seu código terá um par de números, que pode ser inteiro ou ponto flutuante, e produzirá o número complexo como uma sequência de dígitos binários. O primeiro número será real, o segundo número de entrada será o valor imaginário. Um ponto binário deve ser impresso apenas se houver posições numéricas diferentes de zero abaixo de 1 (ou seja, se alguma das posições para -0,5 i , -0,25, 0,125 i , etc. tiver um dígito diferente de zero). Zeros à esquerda e à direita não são permitidos, exceto por um único dígito zero imediatamente antes do ponto binário, se não houver outros dígitos. A saída não deve começar com um ponto binário (* 00.1- errado, 0.1- certo, * .1- errado, * 0.10- errado). Você pode assumir que todos os números de entrada terão representações binárias finitas.

Números de teste:

re   im            output
 0    0                 0
 1    0                 1
 2    0                10
 3    0                11
 4    0         100110000
-1    0             10011
-2    0             10010
-3    0             10001
 0    1               100.1
 0    2               100
 0    3              1000.1
 0    4              1000
 0   -1                 0.1
 0   -2           1001100
 0   -3           1001100.1
 3    4              1011
 4    3         100111000.1
 6   -9         101110010.1
-6    9       10011100110.1
-9   -6           1110111
 0.5 14.125   10011001101.001001

Nota: A saída de todos os valores inteiros terminará .1se a parte imaginária for ímpar.

Código-golfe padrão.

CJ Dennis
fonte
4
Este é um bom desafio, mas a explicação pode ser bem mais clara. Você deve esclarecer o processo: vai de números complexos, a uma representação quaternária intercalada , a um mapeamento de representação binária0 → 00, 1 → 01, 2 → 10, 3 → 11 .
Lynn
@Mauris Fiz várias edições para abordar seu comentário. Deixe-me saber se posso melhorar ainda mais.
CJ Dennis
2
E se for recorrente em binário?
Leaky Nun
11
@LeakyNun Diz exatamente o desafio: "Você pode assumir que todos os números de entrada terão representações binárias finitas".
Mego

Respostas:

2

JavaScript (ES6), 340 bytes

f=x=>[0,...x.toString(16)].reverse().map(d=>s=d<'.'?s:d<`0`?d+s.slice(0,-1):`${(c=+`0x${d}`+(c>>4)+m^m)>>2&3}${c&3}`+s,c=s='.',m=x<0?3:12)&&s
g=(s,t,n=s.indexOf`.`,m=t.indexOf`.`)=>n<m?g(0+s,t):n>m?g(s,0+t):t[s.length]?g(s+0,t):s.replace(/\d/g,(c,i)=>`${t[i]>>1}${t[i]&1}${c>>1}${c&1}`).replace(/^0+(\d)|\.?0*$/g,'$1')
(r,i)=>g(f(r),f(i/2))

fconverte um número em base -4(com à direita .se o número for um número inteiro). gpega dois -4números de base , junta-os nas duas extremidades com o mesmo comprimento e .posição, embaralha os dígitos, converte tudo da base 4para a base e 2, finalmente, tira zeros à esquerda e à direita.

Explicação: Para representar o número complexo dado na base modificada 2i, precisamos representar a parte real e metade da parte complexa (ie dividir a parte imaginária por 2i) na base 2i²(ie -4), embaralhar os dígitos juntos e depois convertê-los da base 4para basear 2. Para representar um número real na base -4, começamos com a 4conversão de base . Dígitos alternativos têm o sinal correto (no caso de um número positivo, esses são os dígitos nas posições pares; no caso de um número negativo, esses são os dígitos nas posições ímpares), mas os dígitos restantes têm o sinal errado e uma correção precisa ser aplicada. Exemplos:

 0 -> 000 -> 000 (no correction needed)
 4 -> 010 -> 130 }
 8 -> 020 -> 120 } (correction includes carry)
12 -> 030 -> 110 }

Como você pode ver, a correção é 8menos o dígito original, mod 8. No entanto, um cálculo um pouco mais conveniente é o dígito original, mais 3, xor 3 (na aritmética de número inteiro de 32 bits, poderíamos simplesmente escrever +0xCCCCCCCC^0xCCCCCCCCpara converter o número inteiro de uma só vez). Finalmente, como a correção se aplica a dígitos alternativos, é mais simples fazer uma conversão inicial para a base, 16que automaticamente seleciona pares de 4dígitos básicos e , em seguida, corrige usando um fator igual 3ou 0xCapropriado. Resta apenas ignorar o -sinal.

Neil
fonte
0

Perl - 313 bytes

Como ninguém postou uma resposta ainda, pensei em dar uma resposta.

$r=$ARGV[0];$i=$ARGV[1]/2;$m=1;while($r!=int($r)||$i!=int($i)){$c++;$m*=-1;$i*=4;$r*=4}while($r||$i){$r-=($d[$n++]=$r/$m%4)*$m;$i-=($d[$n++]=$i/$m%4)*$m;$m*=-4}$_=join("",map({sprintf"%02b",$_}reverse splice(@d,$c*2)))||"0";@d and$_.=".".join("",map({sprintf"%02b",$_}reverse@d));s/^0+1/1/;s/(\.\d*1)0+$/$1/;print

Tenho certeza de que há muitas oportunidades para jogar golfe ainda mais.

CJ Dennis
fonte