-
Notifications
You must be signed in to change notification settings - Fork 223
/
Copy pathmaximizing-xor.py
122 lines (98 loc) · 3.53 KB
/
maximizing-xor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# POC concept. Currently only finds the best XOR result
# in the whole array
class Node:
def __init__(self):
self.left = None
self.right = None
def is_leaf(self):
return self.left is None and self.right is None
class Trie:
def __init__(self, size):
self.root = Node()
self.size = size
def add(self, number):
node = self.root
for digit in number:
if digit == '1':
if node.right is not None:
node = node.right
else:
node.right = Node()
node = node.right
if digit == '0':
if node.left is not None:
node = node.left
else:
node.left = Node()
node = node.left
def find_xor_max(self, number):
res = ''
untouched = ''
number_bin = dec_to_bin(number)
to_maximize = number_bin
if len(number_bin) > self.size:
to_maximize = number_bin[len(number_bin) - self.size:]
untouched = number_bin[:len(number_bin) - self.size]
elif len(number_bin) < self.size:
to_maximize = buildup_to_len(number_bin, self.size)
#print("untouched: {}".format(untouched))
#print("to maximize: {}".format(to_maximize))
node = self.root
for digit in to_maximize:
if digit == '1':
if node.left is not None:
res += '0'
node = node.left
elif node.right is not None:
res += '1'
node = node.right
elif digit == '0':
if node.right is not None:
res += '1'
node = node.right
elif node.left is not None:
res += '0'
node = node.left
#print("res is {}".format(res))
return bin_to_dec(res) ^ number
def print_trie(self):
if self.root != None:
self._print_trie(self.root, self.size, 0, '')
def _print_trie(self, node, size, depth, result):
if node != None:
#print("size = {} depth = {} node is leaf = {}".format(size, depth, node.is_leaf()))
#if size == depth:
if node.is_leaf() and size == depth:
print(result)
return
self._print_trie(node.left, size, depth+1, result + '0')
self._print_trie(node.right, size, depth+1, result + '1')
def dec_to_bin(number):
return str(bin(number).replace('0b', ''))
def bin_to_dec(number):
return int(number, 2)
def make_arr_bin(arr):
arr_bin = [ dec_to_bin(el) for el in arr ]
return arr_bin
def get_max_len(arr):
return len(dec_to_bin(max(arr)))
def buildup_to_len(number, length):
return '0' * (length - len(number)) + number
def build_trie(arr):
max_number_len = get_max_len(arr)
arr_bin = make_arr_bin(arr)
trie = Trie(max_number_len)
#print("max len = {}".format(max_number_len))
for elem in arr_bin:
trie.add(buildup_to_len(elem, max_number_len))
return trie
if __name__ == "__main__":
p = int(input().strip())
q = int(input().strip())
trie = build_trie(range(p, q+1))
res_max = 0
for a in range(p, q + 1):
get_max = trie.find_xor_max(a)
if get_max > res_max:
res_max = get_max
print(res_max)