Finished 2017/18

This commit is contained in:
FrederikBaerentsen 2024-11-27 23:20:51 +01:00
parent 1ecac41ed4
commit c970981aa9
7 changed files with 463 additions and 6 deletions

View File

@ -76,8 +76,6 @@ with a non-zero value?
Your puzzle answer was `8600`.
The first half of this puzzle is complete! It provides one gold star: \*
## \-\-- Part Two \-\-- {#part2}
As you congratulate yourself for a job well done, you notice that the
@ -134,7 +132,13 @@ executed even its first instruction.
Once both of your programs have terminated (regardless of what caused
them to do so), *how many times did program `1` send a value*?
Answer:
Your puzzle answer was `7239`.
Although it hasn\'t changed, you can still [get your puzzle
Both parts of this puzzle are complete! They provide two gold stars:
\*\*
At this point, you should [return to your Advent calendar](/2017) and
try another puzzle.
If you still want to see it, you can [get your puzzle
input](18/input).

View File

@ -96,7 +96,99 @@ if part == 1:
#########################################
# #
# Part 2 #
# #
# in seperate file #
#########################################
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_1_return(x):
if x in Sets_1:
value = Sets_1[x]
if isinstance(value, str) and not x.lstrip('-').isdigit():
return sets_1_return(value)
return value
elif x.isdigit() or x.lstrip('-').isdigit():
return int(x)
else:
return None
def sets_0_return(x):
if x in Sets_0:
value = Sets_0[x]
if isinstance(value, str) and not x.lstrip('-').isdigit():
return sets_0_return(value)
return value
elif x.isdigit() or x.lstrip('-').isdigit():
return int(x)
else:
return None
instructions = []
Sets_1 = {}
Sets_0 = {}
p_1 = []
p_0 = []
last_sound = 0
if part == 2:
exit()
with open(input_f) as file:
for line in file:
instructions.append(list(parse_input(line.rstrip())))
x = 0
while True:
i = instructions[x]
print(i)
if isinstance(i[1], str):
if i[1] not in Sets:
Sets[i[1]] = 0
if i[0] == 'set':
Sets[i[1]] = int(sets_return(i[2]))
x += 1
elif i[0] == 'add':
Sets[i[1]] += sets_return(i[2])
x += 1
elif i[0] == 'mul':
Sets[i[1]] *= sets_return(i[2])
x += 1
elif i[0] == 'mod':
Sets[i[1]] %= sets_return(i[2])
x += 1
elif i[0] == 'snd':
last_sound = sets_return(i[1])
x += 1
elif i[0] == 'rcv':
if sets_return(i[1]) != 0:
Sets[i[1]] = sets_return(i[1])
print(last_sound)
exit()
x += 1
elif i[0] == 'jgz':
if sets_return(i[1]) > 0:
x += sets_return(i[2])
else:
x += 1
input()

138
2017/18/solution_part2.py Normal file
View File

@ -0,0 +1,138 @@
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))

7
2017/18/test1 Normal file
View File

@ -0,0 +1,7 @@
snd 1
snd 2
snd p
rcv a
rcv b
rcv c
rcv d

41
2017/18/test2 Normal file
View File

@ -0,0 +1,41 @@
set i 31
set a 1
mul p 17
jgz p p
mul a 2
add i -1
jgz i -2
add a -1
set i 127
set p 735
mul p 8505
mod p a
mul p 129749
add p 12345
mod p a
set b p
mod b 10000
snd b
add i -1
jgz i -9
jgz a 3
rcv b
jgz b -1
set f 0
set i 126
rcv a
rcv b
set p a
mul p -1
add p b
jgz p 4
snd a
set a b
jgz 1 3
snd b
set f 1
add i -1
jgz i -11
snd a
jgz f -16
jgz a -19

45
2017/19/19.md Normal file
View File

@ -0,0 +1,45 @@
## \-\-- Day 19: A Series of Tubes \-\--
Somehow, a network packet got
lost
and ended up here. It\'s trying to follow a routing diagram (your puzzle
input), but it\'s confused about where to go.
Its starting point is just off the top of the diagram. Lines (drawn with
`|`, `-`, and `+`) show the path it needs to take, starting by going
down onto the only line connected to the top of the diagram. It needs to
follow this path until it reaches the end (located somewhere within the
diagram) and stop there.
Sometimes, the lines cross over each other; in these cases, it needs to
continue going the same direction, and only turn left or right when
there\'s no other option. In addition, someone has left *letters* on the
line; these also don\'t change its direction, but it can use them to
keep track of where it\'s been. For example:
|
| +--+
A | C
F---|----E|--+
| | | D
+B-+ +--+
Given this diagram, the packet needs to take the following path:
- Starting at the only line touching the top of the diagram, it must
go down, pass through `A`, and continue onward to the first `+`.
- Travel right, up, and right, passing through `B` in the process.
- Continue down (collecting `C`), right, and up (collecting `D`).
- Finally, go all the way left through `E` and stopping at `F`.
Following the path to the end, the letters it sees on its path are
`ABCDEF`.
The little packet looks up at you, hoping you can help it find the way.
*What letters will it see* (in the order it would see them) if it
follows the path? (The routing diagram is very wide; make sure you view
it without line wrapping.)
To begin, [get your puzzle input](19/input).
Answer:

130
2017/19/solution.py Normal file
View File

@ -0,0 +1,130 @@
#!/bin/python3
import sys,re
from pprint import pprint
sys.path.insert(0, '../../')
from fred import list2int
input_f = 'test'
part = 1
#########################################
# #
# Part 1 #
# #
#########################################
grid = []
start = ()
prev = ()
def valid_n(grid,cur):
r,c = cur
count = 0
if grid[r-1][c] != ' ':
count += 1
if grid[r+1][c] != ' ':
count += 1
if grid[r][c+1] != ' ':
count += 1
if grid[r][c-1] != ' ':
count += 1
return count
if part == 1:
with open(input_f) as file:
for line in file:
grid.append(list(line.rstrip()))
for r, row in enumerate(grid):
for c, col in enumerate(row):
print(grid[r][c],end='')
print()
for r, row in enumerate(grid):
for c, col in enumerate(row):
if r == 0:
if grid[r][c] == '|':
start = (r,c)
end = False
cur = start
prev = (-1,-1)
prev_dir = {
'up': False,
'down': False,
'left': False,
'right': False
}
while not end:
r,c = cur
try:
if grid[r-1][c] != ' ' and prev != (r-1,c):
print('up',grid[r-1][c])
prev = cur
prev_dir = {
'up': True,
'down': False,
'left': False,
'right': False
}
cur = (r-1,c)
except Exception as e:
print(e)
try:
if grid[r+1][c] != ' ' and prev != (r+1,c):
print('down',grid[r+1][c])
if valid_n(grid,cur) >= 1 and prev_dir['down']:
prev = cur
prev_dir = {
'up': False,
'down': True,
'left': False,
'right': False
}
cur = (r+1,c)
except Exception as e:
print(e)
try:
if grid[r][c-1] != ' ' and prev != (r,c-1) and not prev_dir['left']:
print('left',grid[r][c-1])
prev = cur
prev_dir = {
'up': False,
'down': False,
'left': True,
'right': False
}
cur = (r,c-1)
except Exception as e:
print(e)
try:
if grid[r][c+1] != ' ' and prev != (r,c+1) and not prev_dir['right']:
print('right',grid[r][c+1])
prev = cur
prev_dir = {
'up': False,
'down': False,
'left': False,
'right': True
}
cur = (r,c+1)
except Exception as e:
print(e)
input()
#########################################
# #
# Part 2 #
# #
#########################################
if part == 2:
exit()