Advertisement
mgla

Advent of Code 2023 - Day 22

Dec 22nd, 2023 (edited)
817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.56 KB | None | 0 0
  1. using System.Diagnostics;
  2.  
  3. var input = File.ReadAllLines("input.txt");
  4.  
  5. var bricks = new List<Brick>();
  6.  
  7. foreach (var line in input)
  8. {
  9.     var coords = line.Split('~', ',').Select(int.Parse).ToArray();
  10.     var brick = new Brick(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
  11.     bricks.Add(brick);
  12.     Debug.Assert(brick.X1 <= brick.X2 && brick.Y1 <= brick.Y2 && brick.Z1 <= brick.Z2);
  13. }
  14.  
  15. bricks = [..bricks.OrderBy(b => b.Z1)];
  16.  
  17. //Bricks start falling downwards. We have ordered them by Z1, so we can just iterate over them.
  18. for (var i = 0; i < bricks.Count; i++)
  19. {
  20.     var brick = bricks[i];
  21.     var z = brick.Z1;
  22.  
  23.     while (z > 0)
  24.     {
  25.         var supportingBricks = bricks.Where(b =>
  26.                 b.Z2 == z - 1 &&
  27.                 brick.Xs.Intersect(b.Xs).Any() &&
  28.                 brick.Ys.Intersect(b.Ys).Any())
  29.             .ToList();
  30.  
  31.         if (supportingBricks.Count > 0 || z == 1)
  32.         {
  33.             foreach (var b in supportingBricks)
  34.             {
  35.                 b.Above.Add(brick);
  36.                 brick.Supporters.Add(b);
  37.             }
  38.             bricks[i] = brick;
  39.             break;
  40.         }
  41.  
  42.         z--;
  43.         brick = brick with { Z1 = z, Z2 = z + brick.Zs.Length - 1 };
  44.     }
  45. }
  46.  
  47. // We have the list of bricks and their connections, now we can just count the bricks
  48. // that are not the only supporter for all bricks placed above them.
  49. Console.WriteLine($"Part 1: {bricks.Count(b => b.Above.All(a => a.Supporters.Count > 1))}");
  50.  
  51. var part2 = 0;
  52.  
  53. foreach (var brick in bricks)
  54. {
  55.     var queue = new Queue<Brick>();
  56.     queue.Enqueue(brick);
  57.     var disintegrated = new HashSet<Brick>();
  58.  
  59.     while (queue.TryDequeue(out var currentBrick))
  60.     {
  61.         disintegrated.Add(currentBrick);
  62.        
  63.         // Count all bricks that are supported by the current brick and all their other supporters, if any,
  64.         // are already disintegrated, and enqueue them to be processed.
  65.         foreach (var above in currentBrick.Above.Where(above => above.Supporters.All(disintegrated.Contains)))
  66.         {
  67.             part2++;
  68.             queue.Enqueue(above);
  69.         }
  70.     }
  71. }
  72.  
  73. Console.WriteLine($"Part 2: {part2}");
  74.  
  75. internal record Brick(int X1, int Y1, int Z1, int X2, int Y2, int Z2)
  76. {
  77.     public List<Brick> Above { get; set; } = [];
  78.     public List<Brick> Supporters { get; set; } = [];
  79.  
  80.     public int[] Xs => Enumerable.Range(X1, X2 - X1 + 1).ToArray();
  81.     public int[] Ys => Enumerable.Range(Y1, Y2 - Y1 + 1).ToArray();
  82.     public int[] Zs => Enumerable.Range(Z1, Z2 - Z1 + 1).ToArray();
  83. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement