前書き
0から1までのすべての有理数は、最終的に周期的なビットシーケンスとして表すことができます。たとえば、11/40のバイナリ表現は
0.010 0011 0011 0011 ...
ここで、0011
部品は無期限に繰り返されます。この表現を見つける1つの方法は次のとおりです。r = 11/40で開始し、それを繰り返し2倍して小数部分を取得し、1を超えたときに記録します。rの値が繰り返されると、ループに入ったことを確認できます。
1. r = 11/40
2. 2*r = 11/20 < 1 -> next bit is 0, r = 11/20
3. 2*r = 11/10 >= 1 -> next bit is 1, r = 2*r - 1 = 1/10
4. 2*r = 1/5 < 1 -> next bit is 0, r = 1/5
5. 2*r = 2/5 < 1 -> next bit is 0, r = 2/5
6. 2*r = 4/5 < 1 -> next bit is 0, r = 4/5
7. 2*r = 8/5 >= 1 -> next bit is 1, r = 2*r - 1 = 3/5
8. 2*r = 6/5 >= 1 -> next bit is 1, r = 2*r - 1 = 1/5, same as in 4.
The loop 5. -> 6. -> 7. -> 8. now repeats.
バイナリ文字列から11/40に戻すには、次の式を使用できます
(int(prefix) + int(suffix)/(2^len(suffix) - 1)) / 2^len(prefix)
どこprefix
が最初の部分010
でsuffix
あり、繰り返し部分0011
でありint
、バイナリ文字列を整数に変換します。
このような表現が2つある場合、それらに対してビット単位のXOR演算を実行できます。結果のシーケンスも周期的であるため、有理数を表します。
一部の有理数には、2つのバイナリ表現があります。
1/4 = 0.010000000...
= 0.001111111...
これらの選択は、ビット単位のXORの結果に影響を与える可能性があります。これらの場合、前者の表現を使用します。これには無限に多くの0があります。
タスク
入力は、半開区間[0,1)の2つの有理数です。出力は、入力に適用されるビットごとのXOR演算の結果であり、有理数として表されます。どちらの入力もそうでない場合でも、出力は1になる可能性があることに注意してください。
入力と出力の正確な形式は柔軟ですが、各有理数は分子と分母の2つの整数で表現する必要があります(0と1は例外として0
、1
必要に応じて表現できます)。入力は最低の用語で表現されると仮定できます。出力は最低の用語で表現する必要があります。組み込みの有理数型は、これらの制限を満たしている限り、受け入れ可能な形式です。言語によって課される整数の境界は無視できますが、アルゴリズムはすべての有理数に対して理論的に機能するはずです。
最も低いバイトカウントが優先されます。標準のコードゴルフ規則が適用されます。
例
入力11/40および3/7を考慮してください。パイプで繰り返し部分を区切って、それらの表現を上下に記述し|
ます。次に、同じ長さの繰り返し部分を抽出し、それらとその前の部分にビット単位のXORを適用します。
11/40 = 0. 0 1 0|0 0 1 1|0 0 1 1|0 0 1 1|0 0 1 1|0 0 1 1|0 0 1 1|0 0 1 ...
3/7 = 0.|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|0 1 1|...
-> 0. 0 0 1|0 1 0 1 1 1 1 0 1 0 0 0|0 1 0 1 1 1 1 0 1 0 0 0|0 1 0 ...
結果の有理数は89/520です。
テストケース
0 0 -> 0
1/2 1/2 -> 0
1/2 1/4 -> 3/4
1/3 2/3 -> 1
1/2 3/4 -> 1/4
5/8 1/3 -> 23/24
1/3 1/5 -> 2/5
15/16 3/19 -> 257/304
15/16 257/304 -> 3/19
3/7 11/40 -> 89/520
5/32 17/24 -> 59/96
16/29 16/39 -> 621001733121535520/696556744961512799
000...
は、この場合に終わる表現を選択する必要があることは暗黙的です(アルゴリズムをで使用した場合に得られるものでもありますr
)。例えば、場合に5/8, 1/3
我々が得る23/24
我々が拡大選ぶため0.101000...
のために5/8
。私たちが代わりに選択した場合0.10011111...
のように5/8
、XORがなった後の結果は19/24
、これは間違っています。関連するウィキペディア:0.999 ...
(a ^ b) ^ b == a
は異なり保持されないことを意味します。例えば(19/24 ^ 1/3) ^ 1/3 != 19/24
。そのため、このことについてかなり興奮しています。(