138 lines
4.2 KiB
Python
138 lines
4.2 KiB
Python
import sys,re,asyncio
|
|
|
|
input_f = 'input'
|
|
|
|
def parse_input(input_str):
|
|
pattern = r"^([a-zA-Z]{3})\s{1}(\w)?\s?(-?\w+)$"
|
|
match = re.match(pattern, input_str)
|
|
if match:
|
|
if match.group(2):
|
|
return match.group(1),match.group(2),match.group(3)
|
|
else:
|
|
return match.group(1),match.group(3)
|
|
return None
|
|
|
|
def sets_return(value, sets):
|
|
if value in sets:
|
|
result = sets[value]
|
|
if isinstance(result, str) and not value.lstrip('-').isdigit():
|
|
return sets_return(result, sets)
|
|
return result
|
|
elif value.isdigit() or value.lstrip('-').isdigit():
|
|
return int(value)
|
|
return None
|
|
|
|
async def loop0(instructions,p_0, p_1,sets_0,state):
|
|
x = 0
|
|
while 0 <= x < len(instructions):
|
|
i = instructions[x]
|
|
if i[0] == 'set':
|
|
sets_0[i[1]] = sets_return(i[2],sets_0)
|
|
x += 1
|
|
elif i[0] == 'add':
|
|
sets_0[i[1]] += sets_return(i[2],sets_0)
|
|
x += 1
|
|
elif i[0] == 'mul':
|
|
sets_0[i[1]] *= sets_return(i[2],sets_0)
|
|
x += 1
|
|
elif i[0] == 'mod':
|
|
sets_0[i[1]] %= sets_return(i[2],sets_0)
|
|
x += 1
|
|
elif i[0] == 'snd':
|
|
await p_1.put(sets_return(i[1],sets_0))
|
|
#print('P0 send', sets_0_return(i[1]),sets_0)#,'p_1',p_1)
|
|
x += 1
|
|
elif i[0] == 'rcv':
|
|
if p_0.empty():
|
|
state["loop0_waiting"] = True
|
|
if state["loop1_waiting"]: # Both loops are stuck
|
|
print(f"Program exiting. Loop1 'snd' count: {state['count']}")
|
|
return
|
|
await asyncio.sleep(0.1)
|
|
else:
|
|
state["loop0_waiting"] = False
|
|
sets_0[i[1]] = await p_0.get()
|
|
#print('P0 recv', sets_0[i[1]],sets_0)#,'p_0',p_0)
|
|
x += 1
|
|
elif i[0] == 'jgz':
|
|
if sets_return(i[1],sets_0) > 0:
|
|
x += sets_return(i[2],sets_0)
|
|
else:
|
|
x += 1
|
|
await asyncio.sleep(0.01)
|
|
|
|
async def loop1(instructions,p_0, p_1,sets_1,state):
|
|
x = 0
|
|
while 0 <= x < len(instructions):
|
|
i = instructions[x]
|
|
if i[0] == 'set':
|
|
sets_1[i[1]] = sets_return(i[2],sets_1)
|
|
x += 1
|
|
elif i[0] == 'add':
|
|
sets_1[i[1]] += sets_return(i[2],sets_1)
|
|
x += 1
|
|
elif i[0] == 'mul':
|
|
sets_1[i[1]] *= sets_return(i[2],sets_1)
|
|
x += 1
|
|
elif i[0] == 'mod':
|
|
sets_1[i[1]] %= sets_return(i[2],sets_1)
|
|
x += 1
|
|
elif i[0] == 'snd':
|
|
await p_0.put(sets_return(i[1],sets_1))
|
|
state["count"] += 1
|
|
print(state["count"])
|
|
x += 1
|
|
elif i[0] == 'rcv':
|
|
if p_1.empty():
|
|
state["loop1_waiting"] = True
|
|
if state["loop0_waiting"]: # Both loops are stuck
|
|
print(f"Program exiting. Loop1 'snd' count: {state['count']}")
|
|
return
|
|
await asyncio.sleep(0.1)
|
|
|
|
else:
|
|
state["loop1_waiting"] = False
|
|
sets_1[i[1]] = await p_1.get()
|
|
#print('P1 recv', sets_1[i[1]],sets_1) #,'p_1',p_1)
|
|
#condition.notify_all()
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif i[0] == 'jgz':
|
|
if sets_return(i[1],sets_1) > 0:
|
|
x += sets_return(i[2],sets_1)
|
|
else:
|
|
x += 1
|
|
await asyncio.sleep(0.01)
|
|
|
|
async def main(instructions):
|
|
p_0 = asyncio.Queue()
|
|
p_1 = asyncio.Queue()
|
|
sets_0 = {'p': 0}
|
|
sets_1 = {'p': 1}
|
|
state = {
|
|
"loop0_waiting": False,
|
|
"loop1_waiting": False,
|
|
"count": 0
|
|
}
|
|
# Create tasks for the two loops
|
|
#task1 = asyncio.create_task(loop0(instructions[:],p_0,p_1))
|
|
#task2 = asyncio.create_task(loop1(count,instructions[:],p_0,p_1))
|
|
|
|
|
|
|
|
await asyncio.gather(
|
|
loop0(instructions, p_0, p_1, sets_0, state),
|
|
loop1(instructions, p_0, p_1, sets_1, state)
|
|
)
|
|
|
|
instructions = []
|
|
|
|
with open(input_f) as file:
|
|
for line in file:
|
|
instructions.append(list(parse_input(line.rstrip())))
|
|
|
|
|
|
asyncio.run(main(instructions)) |