introduction
Chaque nombre rationnel entre 0 et 1 peut être représenté comme une séquence de bits éventuellement périodique. Par exemple, la représentation binaire de 11/40 est
0.010 0011 0011 0011 ...
où la 0011
partie se répète indéfiniment. Une façon de trouver cette représentation est la suivante. Commencez par r = 11/40 , puis doublez-le à plusieurs reprises et prenez la partie fractionnaire, en enregistrant quand il va au-dessus de 1. Lorsque la valeur de r se répète, vous savez que vous avez entré une boucle.
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.
Pour revenir de la chaîne binaire à 11/40, vous pouvez utiliser la formule
(int(prefix) + int(suffix)/(2^len(suffix) - 1)) / 2^len(prefix)
où prefix
est la partie initiale 010
, suffix
est la partie répétitive 0011
et int
convertit une chaîne binaire en entier.
Étant donné deux de ces représentations, nous pouvons effectuer l'opération XOR au niveau du bit sur elles. La séquence résultante sera également périodique, elle représente donc un nombre rationnel.
Pour certains nombres rationnels, il existe deux représentations binaires.
1/4 = 0.010000000...
= 0.001111111...
Le choix entre eux peut affecter le résultat du XOR au niveau du bit. Dans ces cas, nous utilisons l'ancienne représentation, qui a une infinité de 0.
La tâche
Vos entrées sont deux nombres rationnels dans l'intervalle semi-ouvert [0,1). Votre sortie doit être le résultat de l'opération XOR au niveau du bit appliquée aux entrées, exprimée en nombre rationnel. Notez que la sortie peut être 1, même si aucune des entrées ne l'est.
Les formats exacts d'entrée et de sortie sont flexibles, mais chaque nombre rationnel doit être représenté par deux entiers, le numérateur et le dénominateur (à l'exception de 0 et 1, qui peuvent être représentés comme 0
et 1
si vous le souhaitez). Vous pouvez supposer que les entrées sont exprimées en termes les plus bas. La sortie doit être exprimée en termes les plus bas. Un type de nombre rationnel intégré est un format acceptable, tant qu'il satisfait à ces restrictions. Vous pouvez ignorer toutes les limites des entiers imposées par votre langage, mais votre algorithme devrait théoriquement fonctionner pour tous les nombres rationnels.
Le nombre d'octets le plus bas gagne. Les règles de code-golf standard s'appliquent.
Exemple
Considérez les entrées 11/40 et 3/7. Nous écrivons leurs représentations les unes au-dessus des autres, délimitant les parties répétitives par des tuyaux |
. Ensuite, nous extrayons des parties répétitives de longueurs égales et leur appliquons un XOR au niveau du bit et les parties qui les précèdent.
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 ...
Le nombre rationnel résultant est 89/520.
Cas de test
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...
dans ce cas (ce qui est également ce que nous obtenons si nous utilisons l'algorithme avecr
). Par exemple, dans le cas où5/8, 1/3
nous obtenons23/24
parce que nous choisissons l'extension0.101000...
pour5/8
. Si nous choisissons plutôt0.10011111...
as5/8
, le résultat après XOR devient19/24
, donc c'est faux. Lié à Wikipedia: 0.999 ...(a ^ b) ^ b == a
il ne tient pas. Par exemple(19/24 ^ 1/3) ^ 1/3 != 19/24
. Cela m'a fait perdre un peu d'enthousiasme à ce sujet :(Réponses:
Python 3,
193164 octetsPrend l'entrée comme le
fractions.Fraction
type de Python 3 et la sort également.Fait amusant (vous pouvez facilement le montrer en utilisant des fonctions de génération), si vous passez
(a<.5)^(b<.5)
à((a>=.5)and(b>=.5))
ci-dessus, vous obtenez le binaire ET entre deux nombres rationnels. Appelez çand(a, b)
. Alors nous avonsa + b - 2*nd(a, b) = x(a, b)
!la source
JavaScript, 141 octets
Ne fonctionnera pas pour le dernier cas de test (débordement d'entier). Entrez 4 nombres pour
p/q xor r/s
, sortez un tableau avec deux nombres. Pour testcase0, 0
, vous devez saisir0, 1, 0, 1
.Comment:
(Tous les nombres décrits ici sont sous forme binaire.)
b
, quib = 10 ^ p - 10 ^ q (p, q are integers, p > q); and b = 0 (mod q); and b = 0 (mod s)
;x = p * b / q
,y = r * b / q
; Convertirp / q
,r / s
enx / b
ety / b
;o = 10 ^ (p - q) - 1
; scissionx
,y
à[x % o, x / o]
,[y % o, y / o]
; obtenir xor pour chaque partie[x % o xor y % o, x / o xor y / o]
et rejoindre à nouveau(x % o xor y % o) + (x / o xor y / o) * o
; Donnez-le commea
;a = 0
, la réponse est0
(ou0 / 1
); Sinon, laissezu = gcd(a, b)
; la réponse est(a/u)
et(b/u)
.Afficher l'extrait de code
la source