Day 18: Ram Run
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 2 points
C#
using QuickGraph;
using QuickGraph.Algorithms.ShortestPath;
namespace aoc24;
public class Day18 : Solver {
private int width = 71, height = 71, bytes = 1024;
private HashSet<(int, int)> fallen_bytes;
private List<(int, int)> fallen_bytes_in_order;
private record class Edge((int, int) Source, (int, int) Target) : IEdge<(int, int)>;
private DelegateVertexAndEdgeListGraph<(int, int), Edge> MakeGraph() => new(GetAllVertices(), GetOutEdges);
private readonly (int, int)[] directions = [(-1, 0), (0, 1), (1, 0), (0, -1)];
private bool GetOutEdges((int, int) arg, out IEnumerable<Edge> result_enumerable) {
List<Edge> result = [];
foreach (var (dx, dy) in directions) {
var (nx, ny) = (arg.Item1 + dx, arg.Item2 + dy);
if (nx < 0 || ny < 0 || nx >= width || ny >= height) continue;
if (fallen_bytes.Contains((nx, ny))) continue;
result.Add(new(arg, (nx, ny)));
}
result_enumerable = result;
return true;
}
private IEnumerable<(int, int)> GetAllVertices() {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
yield return (i, j);
}
}
}
public void Presolve(string input) {
fallen_bytes_in_order = [..input.Trim().Split("\n")
.Select(line => line.Split(","))
.Select(pair => (int.Parse(pair[0]), int.Parse(pair[1])))];
fallen_bytes = [.. fallen_bytes_in_order.Take(bytes)];
}
private double Solve() {
var graph = MakeGraph();
var search = new AStarShortestPathAlgorithm<(int, int), Edge>(graph, _ => 1, vtx => vtx.Item1 + vtx.Item2);
search.SetRootVertex((0, 0));
search.ExamineVertex += vertex => {
if (vertex.Item1 == width - 1 && vertex.Item2 == width - 1) search.Abort();
};
search.Compute();
return search.Distances[(width - 1, height - 1)];
}
public string SolveFirst() => Solve().ToString();
public string SolveSecond() {
foreach (var b in fallen_bytes_in_order[bytes..]) {
fallen_bytes.Add(b);
if (Solve() > width*height) return $"{b.Item1},{b.Item2}";
}
throw new Exception("solution not found");
}
}