Metadata
-
Date
-
Tagged
-
Part of series
- Advent of Code 2024 Day 1
- Advent of Code 2024 Day 2
- Advent of Code 2024 Day 3
- Advent of Code 2024 Day 4
- Advent of Code 2024 Day 5
- Advent of Code 2024 Day 6
- Advent of Code 2024 Day 7
- Advent of Code 2024 Day 8
- Advent of Code 2024 Day 9
- Advent of Code 2024 Day 10
- Advent of Code 2024 Day 11
- Advent of Code 2024 Day 12
- Advent of Code 2024 Day 13
- Advent of Code 2024 Day 14
- Advent of Code 2024 Day 15
- Advent of Code 2024 Day 16
- Advent of Code 2024 Day 17
- Advent of Code 2024 Day 18
- Advent of Code 2024 Day 19
- Advent of Code 2024 Day 20
- Advent of Code 2024 Day 21
- Advent of Code 2024 Day 22
- Advent of Code 2024 Day 23
- Advent of Code 2024 Day 24
- Advent of Code 2024 Day 25
-
Older post
-
Newer post
Advent of Code 2024 Day 6
Day 6: Guard Gallivant
https://adventofcode.com/2024/day/6
Another day, another familiar location.
You are at a manufacturing facility, and make a map of the area, that’s today’s input.
An example input looks like this:
- A
.
is an empty spot - A
#
is a blocked spot - The
^
is a guard that is facing north.
The guard can only move forward, one step at a time. When the guard comes across a blocked spot, they turn 90 degrees clockwise, then go forward again.
Parsing
A 2D puzzle, those are familiar! As a lot of previous days in advent of code, I took the very verbose way of parsing on purpose, for clarity.
I return:
- The starting position of the guard (with numbers that can go negative, because calculating offsets is in my future!)
- The 2D-grid with a character in each position, replacing the position the guard was in with an empty space.
Part 1
The question asks how many positions on your map are in the guard’s patrol path before they leave the area your map describes.
Helper
The helper for part 1 will do most of the heavy lifting today. It returns a set of all the positions the guard visited during their patrol.
I started off by defining some variables to keep track of during the loop (the guard’s patrol):
dir
: either^
,>
,v
, or<
depending on which way the guard is facingpos
: the current position of the guard, has a row index and a column index into the mapseen
: A set of all positions the guard visits before leaving the bounds of the map
I defined a little helping constant that allows me to look up how the position should change given a direction.
The loop does the loopy thing while the current position is inside the grid.
It inserts the current position into a set of visited positions.
Then it calculates what the new position would be if the guard kept walking in the current direction.
If that new position is a blocked spot #
, the guard turns clockwise, if it’s empty, the current position is updated to that new postion and the loop body ends.
Once the loop exits, the guard left the grid, and the set is filled with locations they visited.
Part 1 code
Part 2
The historians you are with need more time to search before the guard leaves the grid. It is possible to place 1 extra obstruction, and cause the guard to walk loops inside the grid!
The question asks how many spaces you could place that single obstruction to cause the guard to walk loops.
The question has the caveat that the obstruction can’t be placed at the guard’s starting position, because the guard would see it!
I don’t know why 1 space in front of the guard is fine, but I’ll pretend it’s a really nearsighted guard that lost their glasses. Oh, and blasting loud jingle bells music as to not hear nearby obstructions being placed.
(Ah, overthinking a pretend backstory for a coding puzzle … I’m fun at parties!)
Helper
The helper function for part 2 detects a loop given some starting conditions. Instead of returning the visited positions, it returns a boolean signalling if there is a loop or not. It is very similar to the helper for part 1
The most important change is that it no longer tracks 2 position coordinated in the set, but a (position, direction) pair. After all, the guard could cross their path without being in a loop, but if they revisit a location facing the same direction, that’s a loop.
Part 2 code
That helper makes the code for the main part_2
method fairly short.
It starts by getting all the original positions the guard visits.
In each spot, it places an obstacle, checks if that would cause a loop, and increments a counter if it does.
Extra credit
Faster would be tracking the seen positions and directions not in a set, but in a 3D-list.
I did this and while my solution for part 1 was orders of magnitude faster, the part 2 solution was twice as slow, so I didn’t write that one up.