-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproblem6.py
More file actions
104 lines (87 loc) · 2.96 KB
/
Copy pathproblem6.py
File metadata and controls
104 lines (87 loc) · 2.96 KB
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
# This problem was asked by Google.
# An XOR linked list is a more memory
# efficient doubly linked list.
# Instead of each node holding next and prev fields,
# it holds a field named both, which is an XOR
# of the next node and the previous node.
# Implement an XOR linked list;
# it has an add(element) which adds the element to
# the end, and a get(index) which returns the node
# at index.
# If using a language that has no pointers
# (such as Python), you can assume you have access
# to get_pointer and dereference_pointer functions
# that converts between nodes and memory addresses.
#The function I use to get a node by its memory address
def get_by_address(address, global_vars):
if address == 0:
return None
result = [x for x in global_vars.values() if id(x) == address]
if(len(result)):
return result[0]
else:
return None
class Node:
def __init__(self, val, both):
self.val = val
self.both = both
class XORLinkedList:
def __init__(self):
self.first = None
self.last = None
#Mainly used for testing, no need to
def print_(self):
if not self.first:
return
else:
current = self.first
prev = None
next = 0 ^ current.both
print(current.val)
while current is not self.last:
prev = id(current)
current = get_by_address(next, globals())
print(current.val)
next = prev ^ current.both
def empty(self):
return self.first is None and self.last is None
#Nothing much here, mainly messing around with the 'both' attribute
def add(self, node):
if self.empty():
node.both = 0
self.first = node
self.last = node
else:
self.last.both = self.last.both ^ id(node)
node.both = id(self.last)
self.last = node
def get(self, index):
if self.first is None:
raise Exception('Out of bound')
current = self.first
last = 0
#using the XOR operation here to find the address of the next node
next = last ^ current.both
for _ in range(index):
#if this evaluates to true, we have reached the end of the list -> the
#index is too big
if next == 0:
raise Exception('Out of bound')
last = current
#getting the nodde object by its address here
current = get_by_address(next, globals())
next = id(last) ^ current.both
return current
first_node = Node('first', 0)
second_node = Node('second', 0)
third_node = Node('third', 0)
fourth_node = Node('fourth', 0)
fifth_node = Node('fifth',0)
def main():
xor_list = XORLinkedList()
xor_list.add(first_node)
xor_list.add(second_node)
xor_list.add(third_node)
print(xor_list.get(2).val)
if __name__ == '__main__':
main()