2進数で4進数の虚数の基数を出力する


17

2進数として表示されるクォーター虚数ベースを出力する関数またはプログラムを作成します。基数は2 iで、iは-1の平方根です。iの詳細については、複素数を参照してください。各実数部と虚数部は前の実数部と虚数部の-4倍であるため、各桁の位置は0〜3(4進)になります。:バイナリでの四桁の数字は次のとおりであり、、&。0: 001: 012: 103: 11

桁位置の内訳:

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)

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)

1100.1は3x2 i + 2x-0.5 i = 6 i + -i = 5 iです。

コードは、整数または浮動小数点の数値のペアを受け取り、複素数を2進数の文字列として出力します。最初の数は実数で、2番目の入力数は虚数です。1以下の非ゼロ数位置がある場合、バイナリポイントのみ(すなわち用-0.5位置のいずれかの印刷されなければならないI 0.125、-0.25、iは等、非ゼロの桁を有します)。先行ゼロと後続ゼロは許可されません。ただし、他の数字がない場合は、2進小数点の直前の単一のゼロ桁を除きます。出力は、2進小数点(* 00.1-間違っている、0.1-正しい、* .1-間違っている、* 0.10-間違っている)で始まってはなりません。すべての入力数が有限のバイナリ表現を持っていると仮定することができます。

テスト番号:

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

注:.1虚数部が奇数の場合、すべての整数値の出力は終了します。

標準コードゴルフ。


4
これは良い挑戦ですが、説明はもっと明確になるでしょう。プロセスを明確にする必要があります。それは、複素数から、インターリーブされた4 表現、2進表現マッピングになり0 → 00, 1 → 01, 2 → 10, 3 → 11ます。
リン

@Maurisあなたのコメントに対処するために、たくさんの編集を行いました。さらに改善できるかどうか教えてください。
CJデニス

2
バイナリで繰り返し発生する場合はどうなりますか?
漏れの修道女

1
@LeakyNunチャレンジの中で、「すべての入力数には有限のバイナリ表現があると仮定するかもしれません」と言っています。
MEGO

回答:


2

JavaScript(ES6)、340バイト

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

f 数値を基数に変換します -4.数値が整数の場合は末尾に付きます)。g2つの基数を取り-4、それらを同じ長さと.位置に両端で埋め込み、数字を一緒にシャッフルし、すべてを基数から基数4に変換し2、最後に先頭と末尾のゼロを取り除きます。

説明:指定された複素数を修正ベース2iで表すには、実部と複素部の半分(つまり、虚部をで割る2i)をベース2i²(つまり-4)で表し、数字をシャッフルしてから、ベースから変換する必要があります4ベースに2。基数で実数を表すために-4、基数4変換から始めます。代替数字には正しい符号があります(正の数の場合、これらは偶数位置の数字です;負の数の場合、これらは奇数位置の数字です)が、残りの数字は間違った符号を持ち、修正を適用する必要があります。例:

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

ご覧のとおり、修正は8元の桁modを引いたもの8です。ただし、少し便利な計算は、元の数字に3、xまたは3を加えたものです(実際、32ビット整数演算では+0xCCCCCCCC^0xCCCCCCCC、一度に数全体を変換するために簡単に記述できます)。最後に、修正が代替桁に適用されるため16、基本4桁のペアを自動的にピックアップする基本への初期変換を行う方が簡単で、その後のいずれかの係数を使用して修正します30xC、適切なかのます。-記号を無視するだけです。


0

Perl-313バイト

まだ誰も答えを投稿していないので、私は自分でそれを始めると思いました。

$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

これ以上ゴルフをする機会がたくさんあると確信しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.