Giới thiệu
Mỗi số hữu tỷ từ 0 đến 1 có thể được biểu diễn dưới dạng một chuỗi bit định kỳ cuối cùng. Ví dụ: biểu diễn nhị phân của 11/40 là
0.010 0011 0011 0011 ...
trong đó 0011
phần lặp lại vô thời hạn. Một cách để tìm đại diện này là sau đây. Bắt đầu với r = 11/40 , sau đó lặp lại gấp đôi và lấy phần phân số, ghi lại khi nó vượt lên trên 1. Khi giá trị của r lặp lại, bạn biết bạn đã nhập một vòng lặp.
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.
Để lấy từ chuỗi nhị phân trở về 11/40, bạn có thể sử dụng công thức
(int(prefix) + int(suffix)/(2^len(suffix) - 1)) / 2^len(prefix)
trong đó prefix
là phần ban đầu 010
, suffix
là phần lặp lại 0011
và int
chuyển đổi một chuỗi nhị phân thành số nguyên.
Đưa ra hai biểu diễn như vậy, chúng ta có thể thực hiện thao tác XOR bitwise trên chúng. Trình tự kết quả cũng sẽ là định kỳ, vì vậy nó đại diện cho một số hữu tỷ.
Đối với một số số hữu tỷ, có hai biểu diễn nhị phân.
1/4 = 0.010000000...
= 0.001111111...
Sự lựa chọn giữa chúng có thể ảnh hưởng đến kết quả của XOR bitwise. Trong những trường hợp này, chúng tôi sử dụng đại diện trước đây, có vô số 0.
Nhiệm vụ
Đầu vào của bạn là hai số hữu tỷ trong khoảng thời gian nửa mở [0,1). Đầu ra của bạn sẽ là kết quả của hoạt động XOR bitwise được áp dụng cho các đầu vào, được biểu thị dưới dạng số hữu tỷ. Lưu ý rằng đầu ra có thể là 1, mặc dù cả hai đầu vào đều không.
Các định dạng chính xác của đầu vào và đầu ra là linh hoạt, nhưng mỗi số hữu tỷ phải được biểu thị bằng hai số nguyên, tử số và mẫu số (ngoại trừ 0 và 1, có thể được biểu diễn theo 0
và 1
nếu muốn). Bạn có thể giả định rằng các đầu vào được thể hiện bằng các thuật ngữ thấp nhất. Đầu ra phải được thể hiện bằng các thuật ngữ thấp nhất. Một loại số hợp lý tích hợp là một định dạng có thể chấp nhận, miễn là nó thỏa mãn những hạn chế này. Bạn có thể bỏ qua mọi giới hạn về số nguyên do ngôn ngữ của bạn áp đặt, nhưng về mặt lý thuyết, thuật toán của bạn sẽ hoạt động với tất cả các số hữu tỷ.
Số byte thấp nhất sẽ thắng. Mã tiêu chuẩnLuật áp dụng.
Thí dụ
Hãy xem xét các đầu vào 11/40 và 3/7. Chúng tôi viết các đại diện của họ chồng lên nhau, phân định các phần lặp lại bằng đường ống |
. Sau đó, chúng tôi trích xuất các phần lặp lại có độ dài bằng nhau và áp dụng XOR bitwise cho chúng và các phần trước chúng.
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 ...
Số hữu tỷ kết quả là 89/520.
Các trường hợp thử nghiệm
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...
trường hợp này (cũng là những gì chúng ta nhận được nếu sử dụng thuật toán vớir
). Ví dụ: trong trường hợp5/8, 1/3
chúng tôi nhận được23/24
vì chúng tôi chọn mở rộng0.101000...
cho5/8
. Nếu chúng ta chọn thay vì0.10011111...
như5/8
, kết quả sau khi XOR trở thành19/24
, vì vậy đây là sai. Liên quan đến Wikipedia: 0.999 ...
(a ^ b) ^ b == a
không giữ. Ví dụ (19/24 ^ 1/3) ^ 1/3 != 19/24
. Điều đó khiến tôi mất khá nhiều hứng thú về điều này :(