Вступ
Кожне раціональне число між 0 і 1 може бути представлене як кінцево періодична послідовність бітів. Наприклад, двійкове представлення 11/40 є
0.010 0011 0011 0011 ...
де 0011
частина повторюється нескінченно. Один із способів пошуку цього уявлення полягає в наступному. Почніть з r = 11/40 , потім повторно подвоюйте її і діліть дробову частину, записуючи, коли вона перевищує 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
перетворює двійковий рядок у ціле число.
Враховуючи два таких подання, ми можемо виконувати над ними побітову операцію XOR. Отримана послідовність також буде періодичною, тому вона являє собою раціональне число.
Для деяких раціональних чисел існує два двійкових подання.
1/4 = 0.010000000...
= 0.001111111...
Вибір між ними може вплинути на результат побітового XOR. У цих випадках ми використовуємо колишнє представлення, яке має нескінченно багато 0.
Завдання
Ваші входи - це два раціональних числа в напіввідкритому інтервалі [0,1). Ваш вихід повинен бути результатом побітової операції XOR, застосованої до входів, вираженої як раціональне число. Зауважте, що вихід може бути рівним 1, хоча жоден із входів не є.
Точні формати введення та виведення є гнучкими, але кожне раціональне число повинно бути представлене двома цілими числами - чисельником і знаменником (за винятком 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
. Це змусило мене втратити трохи хвилювання з цього приводу :(