Day 6: Guard Gallivant
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 4 points
C#
public class Day06 : Solver
{
private readonly (int, int)[] directions = [
(0, -1), (1, 0), (0, 1), (-1, 0)
];
private ImmutableArray<string> data;
private int width, height;
private ImmutableHashSet<(int, int)> guard_path;
private int start_x, start_y;
public void Presolve(string input) {
data = input.Trim().Split("\n").ToImmutableArray();
width = data[0].Length;
height = data.Length;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (data[j][i] == '^') {
start_x = i;
start_y = j;
break;
}
}
}
guard_path = Walk().Path.ToImmutableHashSet();
}
private bool IsWithinBounds(int x, int y) => x >= 0 && y >= 0 && x < width && y < height;
private (HashSet<(int, int)> Path, bool IsLoop) Walk((int, int)? obstacle = null) {
int obstacle_x = obstacle?.Item1 ?? -1;
int obstacle_y = obstacle?.Item2 ?? -1;
int direction = 0;
int x = start_x;
int y = start_y;
bool loop = false;
HashSet<(int, int, int)> positions = new();
while (IsWithinBounds(x, y)) {
if (positions.Contains((x, y, direction))) {
loop = true;
break;
}
positions.Add((x, y, direction));
int nx = x + directions[direction].Item1;
int ny = y + directions[direction].Item2;
while (IsWithinBounds(nx, ny) && (data[ny][nx] == '#' || (nx == obstacle_x && ny == obstacle_y))) {
direction = (direction + 1) % 4;
nx = x + directions[direction].Item1;
ny = y + directions[direction].Item2;
}
x = nx;
y = ny;
}
return (positions.Select(position => (position.Item1, position.Item2)).ToHashSet(), loop);
}
public string SolveFirst() => guard_path.Count.ToString();
public string SolveSecond() => guard_path
.Where(position => position != (start_x, start_y))
.Where(position => Walk(position).IsLoop)
.Count().ToString();
}