/
qset_interpreter.py
93 lines (90 loc) · 2.85 KB
/
qset_interpreter.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
class QSet:
def __init__(self, input=None):
self.__repr__=self.__str__
self.qset = {}
if input!=None:
for item in input:
self.add_item(item)
def add_item(self, item, amt=1):
if item in self.qset:
self.qset[item]+=amt
if self.qset[item]==0:
del self.qset[item]
else:
self.qset[item]=amt
def add_qset(self, aqset):
for item in aqset.qset:
self.add_item(item, aqset.qset[item])
def remove_qset(self, aqset):
for item in aqset.qset:
self.add_item(item, -aqset.qset[item])
def contains_qset(self, aqset):
for item in aqset.qset:
if item in self.qset:
if self.qset[item]<aqset.qset[item]:
return False
else:
return False
return True
def is_empty(self):
return len(self.qset)==0
def __str__(self):
return str(self.qset)
def parse(x):
steps = x.strip()
steps = steps.split(',')
reps = []
for step in steps:
rep = [y.strip() for y in step.split('/')]
if len(rep)!=2:
raise Exception("Failed to parse input!")
reps.append(rep)
return [[QSet([] if x.split(' ')==[''] else x.split(' ')) for x in vals] for vals in reps]
def interpret_step(program, qset):
for process in program:
if qset.contains_qset(process[1]):
qset.remove_qset(process[1])
qset.add_qset(process[0])
return False
return True
def interpret(program, input, maxsteps=100000):
try:
program = parse(program)
qset = QSet()
for x in range(len(input)):
if type(input[x]) is int or type(input[x]) is long:
qset.add_item('i%i'%x, input[x])
else:
raise Exception("Invalid input type")
step = 0
while True:
if step==maxsteps:
raise Exception("Too many execution steps!")
ret = interpret_step(program, qset)
if ret:
break
step += 1
success = True
outputs = {}
for key in qset.qset:
if len(key)>1:
if key[0]=="o":
idx = key[1:]
idx = int(idx)
outputs[idx] = qset.qset[key]
else:
success = False
else:
success = False
if success:
outputs_arr = []
for x in range(len(outputs)):
if x in outputs:
outputs_arr.append(outputs[x])
else:
raise Exception("Invalid output!")
return outputs_arr
else:
raise Exception("Invalid output!")
except Exception as e:
return ",".join(e.args)