Salida de números base quater-imaginarios en binario

17

Escriba una función o programa que genere una base Quater-imaginary mostrada como dígitos binarios. La base numérica es 2 i , donde i es la raíz cuadrada de -1. Ver número complejo para más detalles sobre i . Cada posición de dígito puede ir de 0 a 3 (cuaternario), ya que cada parte real e imaginaria es -4 veces más grande que la parte real e imaginaria anterior. Los dígitos cuaternario en binario son como sigue: 0: 00, 1: 01, 2: 10y 3: 11.

Desglose de posiciones de 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)

El número 100110000es 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)

El número 1100.1es 3x2 i + 2x-0.5 i = 6 i + - i = 5 i .

Su código tomará un par de números, que podrían ser enteros o de coma flotante, y generará el número complejo como una cadena de dígitos binarios. El primer número será real, el segundo número de entrada será el valor imaginario. Un punto binario solo debe imprimirse si hay posiciones de números distintos de cero por debajo de 1 (es decir, si alguna de las posiciones para -0.5 i , -0.25, 0.125 i , etc. tiene un dígito distinto de cero). Los ceros iniciales y finales no están permitidos, a excepción de un solo dígito cero inmediatamente antes del punto binario si no hay otros dígitos. La salida no debe comenzar con un punto binario (* 00.1- incorrecto, 0.1- correcto, * .1- incorrecto, * 0.10- incorrecto). Puede suponer que todos los números de entrada tendrán representaciones binarias finitas.

Números de prueba:

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: La salida de todos los valores enteros terminará .1si la parte imaginaria es impar.

Código estándar de golf.

CJ Dennis
fuente
44
Este es un buen desafío, pero la explicación podría ser mucho más clara. Debe aclarar el proceso: va desde números complejos, a una representación cuaternaria intercalada , a un mapeo de representación binaria0 → 00, 1 → 01, 2 → 10, 3 → 11 .
Lynn el
@Mauris He hecho un montón de ediciones para abordar su comentario. Avísame si puedo mejorarlo aún más.
CJ Dennis
2
¿Qué pasa si es recurrente en binario?
Leaky Nun
1
@LeakyNun Dice justo en el desafío: "Puede suponer que todos los números de entrada tendrán representaciones binarias finitas".
Mego

Respuestas:

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))

fconvierte un número en base -4(con el final .si el número es un entero). gtoma dos -4números de base , los coloca en ambos extremos a la misma longitud y .posición, mezcla los dígitos, convierte todo de base 4a base 2, luego finalmente elimina los ceros iniciales y finales.

Explicación: Para representar el número complejo dado en base modificada 2i, necesitamos representar la parte real y la mitad de la parte compleja (es decir, dividir la parte imaginaria por 2i) en base 2i²(es decir -4), mezclar los dígitos y luego convertirlos de base 4a la base 2. Para representar un número real en base -4comenzamos con la 4conversión de base . Los dígitos alternativos tienen el signo correcto (en el caso de un número positivo, estos son los dígitos en las posiciones pares; en el caso de un número negativo, estos son los dígitos en las posiciones impares) pero los dígitos restantes tienen el signo incorrecto y una corrección necesita ser aplicada. Ejemplos:

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

Como puede ver, la corrección es 8menos el dígito original, mod 8. Sin embargo, un cálculo un poco más conveniente es el dígito original, más 3, xo 3 (de hecho, en la aritmética de enteros de 32 bits podríamos simplemente escribir +0xCCCCCCCC^0xCCCCCCCCpara convertir el número entero de una vez). Finalmente, como la corrección se aplica a dígitos alternativos, es más simple hacer una conversión inicial a base 16que automáticamente recoge pares de 4dígitos base , luego corregir usando un factor de uno 3o 0xCsegún sea apropiado. Solo queda ignorar el -letrero.

Neil
fuente
0

Perl - 313 bytes

Como nadie ha publicado una respuesta todavía, pensé en sacarla yo mismo.

$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

Estoy seguro de que hay muchas oportunidades para jugar golf más allá.

CJ Dennis
fuente