Solved 2024/06 P1+P2
This commit is contained in:
parent
6a94713884
commit
4274b0bb89
255
2024/06/6.md
Normal file
255
2024/06/6.md
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
## \-\-- Day 6: Guard Gallivant \-\--
|
||||||
|
|
||||||
|
The Historians use their fancy [device](4) again, this time to whisk you
|
||||||
|
all away to the North Pole prototype suit manufacturing lab\... in the
|
||||||
|
year [1518](/2018/day/5)! It turns out that having direct access to
|
||||||
|
history is very convenient for a group of historians.
|
||||||
|
|
||||||
|
You still have to be careful of time paradoxes, and so it will be
|
||||||
|
important to avoid anyone from 1518 while The Historians search for the
|
||||||
|
Chief. Unfortunately, a single *guard* is patrolling this part of the
|
||||||
|
lab.
|
||||||
|
|
||||||
|
Maybe you can work out where the guard will go ahead of time so that The
|
||||||
|
Historians can search safely?
|
||||||
|
|
||||||
|
You start by making a map (your puzzle input) of the situation. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#..^.....
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
The map shows the current position of the guard with `^` (to indicate
|
||||||
|
the guard is currently facing *up* from the perspective of the map). Any
|
||||||
|
*obstructions* - crates, desks, alchemical reactors, etc. - are shown as
|
||||||
|
`#`.
|
||||||
|
|
||||||
|
Lab guards in 1518 follow a very strict patrol protocol which involves
|
||||||
|
repeatedly following these steps:
|
||||||
|
|
||||||
|
- If there is something directly in front of you, turn right 90
|
||||||
|
degrees.
|
||||||
|
- Otherwise, take a step forward.
|
||||||
|
|
||||||
|
Following the above protocol, the guard moves up several times until she
|
||||||
|
reaches an obstacle (in this case, a pile of failed suit prototypes):
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....^....#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#........
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Because there is now an obstacle in front of the guard, she turns right
|
||||||
|
before continuing straight in her new facing direction:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
........>#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#........
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Reaching another obstacle (a spool of several *very* long polymers), she
|
||||||
|
turns right again and continues downward:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#......v.
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
This process continues for a while, but the guard eventually leaves the
|
||||||
|
mapped area (after walking past a tank of universal solvent):
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#........
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#v..
|
||||||
|
|
||||||
|
By predicting the guard\'s route, you can determine which specific
|
||||||
|
positions in the lab will be in the patrol path. *Including the guard\'s
|
||||||
|
starting position*, the positions visited by the guard before leaving
|
||||||
|
the area are marked with an `X`:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....XXXXX#
|
||||||
|
....X...X.
|
||||||
|
..#.X...X.
|
||||||
|
..XXXXX#X.
|
||||||
|
..X.X.X.X.
|
||||||
|
.#XXXXXXX.
|
||||||
|
.XXXXXXX#.
|
||||||
|
#XXXXXXX..
|
||||||
|
......#X..
|
||||||
|
|
||||||
|
In this example, the guard will visit `41` distinct positions on your
|
||||||
|
map.
|
||||||
|
|
||||||
|
Predict the path of the guard. *How many distinct positions will the
|
||||||
|
guard visit before leaving the mapped area?*
|
||||||
|
|
||||||
|
Your puzzle answer was `5212`.
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
While The Historians begin working around the guard\'s patrol route, you
|
||||||
|
borrow their fancy device and step outside the lab. From the safety of a
|
||||||
|
supply closet, you time travel through the last few months and
|
||||||
|
[record](/2018/day/4) the nightly status of the lab\'s guard post on the
|
||||||
|
walls of the closet.
|
||||||
|
|
||||||
|
Returning after what seems like only a few seconds to The Historians,
|
||||||
|
they explain that the guard\'s patrol area is simply too large for them
|
||||||
|
to safely search the lab without getting caught.
|
||||||
|
|
||||||
|
Fortunately, they are *pretty sure* that adding a single new obstruction
|
||||||
|
*won\'t* cause a time paradox. They\'d like to place the new obstruction
|
||||||
|
in such a way that the guard will get [*stuck in a
|
||||||
|
loop*]{title="This vulnerability was later fixed by having the guard always turn left instead."},
|
||||||
|
making the rest of the lab safe to search.
|
||||||
|
|
||||||
|
To have the lowest chance of creating a time paradox, The Historians
|
||||||
|
would like to know *all* of the possible positions for such an
|
||||||
|
obstruction. The new obstruction can\'t be placed at the guard\'s
|
||||||
|
starting position - the guard is there right now and would notice.
|
||||||
|
|
||||||
|
In the above example, there are only `6` different positions where a new
|
||||||
|
obstruction would cause the guard to get stuck in a loop. The diagrams
|
||||||
|
of these six situations use `O` to mark the new obstruction, `|` to show
|
||||||
|
a position where the guard moves up/down, `-` to show a position where
|
||||||
|
the guard moves left/right, and `+` to show a position where the guard
|
||||||
|
moves both up/down and left/right.
|
||||||
|
|
||||||
|
Option one, put a printing press next to the guard\'s starting position:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
....|..#|.
|
||||||
|
....|...|.
|
||||||
|
.#.O^---+.
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Option two, put a stack of failed suit prototypes in the bottom right
|
||||||
|
quadrant of the mapped area:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
..+-+-+#|.
|
||||||
|
..|.|.|.|.
|
||||||
|
.#+-^-+-+.
|
||||||
|
......O.#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Option three, put a crate of chimney-squeeze prototype fabric next to
|
||||||
|
the standing desk in the bottom right quadrant:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
..+-+-+#|.
|
||||||
|
..|.|.|.|.
|
||||||
|
.#+-^-+-+.
|
||||||
|
.+----+O#.
|
||||||
|
#+----+...
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Option four, put an alchemical retroencabulator near the bottom left
|
||||||
|
corner:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
..+-+-+#|.
|
||||||
|
..|.|.|.|.
|
||||||
|
.#+-^-+-+.
|
||||||
|
..|...|.#.
|
||||||
|
#O+---+...
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Option five, put the alchemical retroencabulator a bit to the right
|
||||||
|
instead:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
..+-+-+#|.
|
||||||
|
..|.|.|.|.
|
||||||
|
.#+-^-+-+.
|
||||||
|
....|.|.#.
|
||||||
|
#..O+-+...
|
||||||
|
......#...
|
||||||
|
|
||||||
|
Option six, put a tank of sovereign glue right next to the tank of
|
||||||
|
universal solvent:
|
||||||
|
|
||||||
|
....#.....
|
||||||
|
....+---+#
|
||||||
|
....|...|.
|
||||||
|
..#.|...|.
|
||||||
|
..+-+-+#|.
|
||||||
|
..|.|.|.|.
|
||||||
|
.#+-^-+-+.
|
||||||
|
.+----++#.
|
||||||
|
#+----++..
|
||||||
|
......#O..
|
||||||
|
|
||||||
|
It doesn\'t really matter what you choose to use as an obstacle so long
|
||||||
|
as you and The Historians can put it into position without the guard
|
||||||
|
noticing. The important thing is having enough options that you can find
|
||||||
|
one that minimizes time paradoxes, and in this example, there are `6`
|
||||||
|
different positions you could choose.
|
||||||
|
|
||||||
|
You need to get the guard stuck in a loop by adding a single new
|
||||||
|
obstruction. *How many different positions could you choose for this
|
||||||
|
obstruction?*
|
||||||
|
|
||||||
|
Your puzzle answer was `1767`.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars:
|
||||||
|
\*\*
|
||||||
|
|
||||||
|
At this point, you should [return to your Advent calendar](/2024) and
|
||||||
|
try another puzzle.
|
||||||
|
|
||||||
|
If you still want to see it, you can [get your puzzle
|
||||||
|
input](6/input).
|
||||||
|
|
125
2024/06/solution.py
Normal file
125
2024/06/solution.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int,get_re,nprint,lprint,loadFile,toGrid,get_value_in_direction,grid_valid
|
||||||
|
|
||||||
|
input_f = 'input'
|
||||||
|
|
||||||
|
part = 2
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
offsets = {
|
||||||
|
'up': (-1, 0),
|
||||||
|
'down': (1, 0),
|
||||||
|
'left': (0, -1),
|
||||||
|
'right': (0, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
next_direction = {
|
||||||
|
'up': 'right',
|
||||||
|
'right': 'down',
|
||||||
|
'down': 'left',
|
||||||
|
'left': 'up'
|
||||||
|
}
|
||||||
|
grid = toGrid(input_f)
|
||||||
|
|
||||||
|
center = ()
|
||||||
|
steps = []
|
||||||
|
for r in range(len(grid)):
|
||||||
|
for c in range(len(grid[0])):
|
||||||
|
if grid[r][c] == '^':
|
||||||
|
center = (r,c)
|
||||||
|
|
||||||
|
pos = center
|
||||||
|
direction = 'up'
|
||||||
|
while grid_valid(pos[0],pos[1],grid):
|
||||||
|
|
||||||
|
#dir = get_value_in_direction(grid, pos)
|
||||||
|
if get_value_in_direction(grid,pos,direction) != '#':
|
||||||
|
if pos not in steps:
|
||||||
|
steps.append(pos)
|
||||||
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
||||||
|
elif get_value_in_direction(grid,pos,direction) == '#':
|
||||||
|
direction = next_direction[direction]
|
||||||
|
|
||||||
|
print(len(steps))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
offsets = {
|
||||||
|
'up': (-1, 0),
|
||||||
|
'down': (1, 0),
|
||||||
|
'left': (0, -1),
|
||||||
|
'right': (0, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
next_direction = {
|
||||||
|
'up': 'right',
|
||||||
|
'right': 'down',
|
||||||
|
'down': 'left',
|
||||||
|
'left': 'up'
|
||||||
|
}
|
||||||
|
|
||||||
|
direction = 'up'
|
||||||
|
|
||||||
|
def isLoop(grid,pos,direction):
|
||||||
|
positions = []
|
||||||
|
|
||||||
|
while grid_valid(pos[0],pos[1],grid):
|
||||||
|
#nprint(grid,pos,'X')
|
||||||
|
if get_value_in_direction(grid,pos,direction) != '#':
|
||||||
|
cur = (pos[0],pos[1],direction)
|
||||||
|
|
||||||
|
if cur not in positions:
|
||||||
|
positions.append(cur)
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
||||||
|
elif get_value_in_direction(grid,pos,direction) == '#':
|
||||||
|
direction = next_direction[direction]
|
||||||
|
#input()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
grid = toGrid(input_f)
|
||||||
|
|
||||||
|
|
||||||
|
start = ()
|
||||||
|
steps = []
|
||||||
|
for r in range(len(grid)):
|
||||||
|
for c in range(len(grid[0])):
|
||||||
|
if grid[r][c] == '^':
|
||||||
|
start = (r,c)
|
||||||
|
|
||||||
|
pos = start
|
||||||
|
while grid_valid(pos[0],pos[1],grid):
|
||||||
|
|
||||||
|
dir = get_value_in_direction(grid, pos)
|
||||||
|
if get_value_in_direction(grid,pos,direction) != '#':
|
||||||
|
if pos not in steps:
|
||||||
|
steps.append(pos)
|
||||||
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
||||||
|
elif get_value_in_direction(grid,pos,direction) == '#':
|
||||||
|
direction = next_direction[direction]
|
||||||
|
steps.remove(start)
|
||||||
|
print(len(steps))
|
||||||
|
result = 0
|
||||||
|
for idx,i in enumerate(steps):
|
||||||
|
print(idx)
|
||||||
|
new_grid = grid[:]
|
||||||
|
new_grid[i[0]][i[1]] = '#'
|
||||||
|
result += isLoop(new_grid,start,'up')
|
||||||
|
new_grid[i[0]][i[1]] = '.'
|
||||||
|
print(result)
|
Loading…
Reference in New Issue
Block a user