Wyjście czwarto-urojonych liczb podstawowych w postaci binarnej

17

Napisz funkcję lub program, który wyprowadza czwartoimienną bazę wyświetlaną jako cyfry binarne. Podstawa liczbowa to 2 i , gdzie i jest pierwiastkiem kwadratowym z -1. Zobacz liczby zespolonej więcej szczegółów dotyczących I . Każda pozycja cyfr może wynosić od 0 do 3 (czwartorzędowa), ponieważ każda część rzeczywista i urojona jest -4 razy większa niż poprzednia część rzeczywista i urojona. Liczby czwartorzędowe w postaci binarnej są następujące:0: 00 , 1: 01, 2: 10i 3: 11.

Podział pozycji cyfr:

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)

Numer 100110000 to 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)

Liczba 1100.1to 3x2 i + 2x-0,5 i = 6 i + - i = 5 i .

Twój kod pobierze parę liczb, które mogą być liczbami całkowitymi lub zmiennoprzecinkowymi, i wyświetli liczbę zespoloną jako ciąg cyfr binarnych. Pierwsza liczba będzie prawdziwa, druga liczba wejściowa będzie wartością urojoną. Punkt binarny musi być wydrukowany tylko wtedy, gdy liczba pozycji niezerowych jest mniejsza niż 1 (tj. Jeśli dowolna z pozycji dla -0,5 i , -0,25, 0,125 i itd. Ma niezerową cyfrę). Zera wiodące i końcowe są niedozwolone, z wyjątkiem pojedynczej cyfry zero bezpośrednio przed punktem binarnym, jeśli nie ma innych cyfr. Dane wyjściowe nie mogą zaczynać się od punktu binarnego (* 00.1- źle, 0.1- dobrze, * .1- źle, * 0.10- źle). Możesz założyć, że wszystkie liczby wejściowe będą miały skończone reprezentacje binarne.

Numery testowe:

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

Uwaga: Dane wyjściowe wszystkich wartości całkowitych zakończą się, .1jeśli część urojona jest nieparzysta.

Standardowy golf.

CJ Dennis
źródło
4
To dobre wyzwanie, ale wyjaśnienie może być o wiele jaśniejsze. Powinieneś wyjaśnić proces: przechodzi od liczb zespolonych, do przeplatanej reprezentacji czwartorzędowej , do binarnego odwzorowania reprezentacji 0 → 00, 1 → 01, 2 → 10, 3 → 11.
Lynn
@ Mauris Dokonałem wielu zmian, aby rozwiązać Twój komentarz. Daj mi znać, czy mogę to jeszcze poprawić.
CJ Dennis
2
Co się stanie, jeśli będzie się powtarzał w systemie binarnym?
Leaky Nun
1
@LeakyNun W samym wyzwaniu jest napisane: „Możesz założyć, że wszystkie liczby wejściowe będą miały skończone reprezentacje binarne”.
Mego

Odpowiedzi:

2

JavaScript (ES6), 340 bajtów

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

fkonwertuje liczbę na podstawową -4(ze znakiem końcowym, .jeśli liczba jest liczbą całkowitą). gbierze dwie -4liczby podstawowe , wstawia je na obu końcach do tej samej długości i .pozycji, tasuje cyfry razem, konwertuje wszystko z bazy4 do podstawy 2, a następnie w końcu usuwa początkowe i końcowe zera.

Objaśnienie: Aby przedstawić podaną liczbę zespoloną w zmodyfikowanej bazie 2i, musimy przedstawić rzeczywistą część i połowę części złożonej (tj. Dzieląc część urojoną 2i) w bazie 2i²(tj. -4), Przetasować cyfry razem, a następnie przekonwertować je z bazy 4oprzeć 2. Aby przedstawić rzeczywistą liczbę w bazie -4, zaczynamy od 4konwersji bazy . Cyfry alternatywne mają poprawny znak (w przypadku liczby dodatniej są to cyfry w pozycjach parzystych; w przypadku liczby ujemnej są to cyfry w pozycjach nieparzystych), ale pozostałe cyfry mają niewłaściwy znak i należy zastosować korektę. Przykłady:

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

Jak widać, korekta jest 8pomniejszona o pierwotną cyfrę, mod 8. Jednak nieco wygodniejszym obliczeniem jest pierwotna cyfra plus 3, xor 3 (w 32-bitowej arytmetyki liczb całkowitych moglibyśmy po prostu napisać, +0xCCCCCCCC^0xCCCCCCCCaby przekonwertować całą liczbę za jednym razem). Wreszcie, ponieważ poprawka dotyczy cyfr alternatywnych, łatwiej jest dokonać wstępnej konwersji na bazę, 16która automatycznie pobiera pary 4cyfr podstawowych , a następnie poprawia ją za pomocą współczynnika jednego 3lub 0xCodpowiednio. Pozostaje tylko zignorować -znak.

Neil
źródło
0

Perl - 313 bajtów

Ponieważ nikt jeszcze nie opublikował odpowiedzi, pomyślałem, że sam ją wykopię.

$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

Jestem pewien, że jest wiele okazji do gry w golfa.

CJ Dennis
źródło