Advertisement
mgla

Advent of Code - 2024 - Day 18

Dec 18th, 2024 (edited)
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.22 KB | None | 0 0
  1. var drops = (await File.ReadAllLinesAsync("input.txt"))
  2.     .Select(line => line.Split(',').Select(int.Parse).ToArray())
  3.     .Select(items => new Position(items[1], items[0])).ToArray();
  4.  
  5. var size = drops.Max(d => Math.Max(d.Row, d.Col)) + 1;
  6. var nanoseconds = size < 70 ? 12 : 1024;
  7.  
  8. var start = new Position(0, 0);
  9. var end = new Position(size - 1, size - 1);
  10.  
  11. Console.WriteLine($"Part 1: {Walk(nanoseconds)}");
  12.  
  13. // Binary search for the first drop that will block the exit.
  14. var min = 0;
  15. var max = drops.Length - 1;
  16. while (max - min > 1)
  17. {
  18.     var mid = (min + max) / 2;
  19.     if (Walk(mid) == -1)
  20.     {
  21.         max = mid;
  22.     }
  23.     else
  24.     {
  25.         min = mid;
  26.     }
  27. }
  28.  
  29. Console.WriteLine($"Part 2: {drops[min].Col},{drops[min].Row}");
  30.  
  31. return;
  32.  
  33. int Walk(int pointInTime)
  34. {
  35.     var corrupted = new bool[size, size];
  36.     for (var i = 0; i < pointInTime; i++)
  37.     {
  38.         var drop = drops[i];
  39.         corrupted[drop.Row, drop.Col] = true;
  40.     }
  41.  
  42.     var queue = new PriorityQueue<Position, int>();
  43.     queue.Enqueue(start, 0);
  44.     var visited = new HashSet<Position>();
  45.  
  46.     while (queue.TryDequeue(out var current, out var time))
  47.     {
  48.         if (current == end)
  49.         {
  50.             return time;
  51.         }
  52.  
  53.         if (!visited.Add(current))
  54.         {
  55.             continue;
  56.         }
  57.  
  58.         foreach (var dir in new[] { Direction.Up, Direction.Down, Direction.Left, Direction.Right })
  59.         {
  60.             var next = current.Move(dir);
  61.             if (!next.OutOfBounds(size) && !corrupted[next.Row, next.Col])
  62.             {
  63.                 queue.Enqueue(next, time + 1);
  64.             }
  65.         }
  66.     }
  67.  
  68.     return -1;
  69. }
  70.  
  71. internal record Direction(int Row, int Col)
  72. {
  73.     public static readonly Direction Up = new(-1, 0);
  74.     public static readonly Direction Down = new(1, 0);
  75.     public static readonly Direction Left = new(0, -1);
  76.     public static readonly Direction Right = new(0, 1);
  77. }
  78.  
  79. internal record Position(int Row, int Col)
  80. {
  81.     public Position Move(Direction dir) => new(Row + dir.Row, Col + dir.Col);
  82.  
  83.     public bool OutOfBounds(int size) => OutOfBounds(0, size);
  84.  
  85.     public bool OutOfBounds(int start, int end) => Row < start || Row >= end || Col < start || Col >= end;
  86. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement