Advertisement
Guest User

Untitled

a guest
Dec 12th, 2024
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.09 KB | None | 0 0
  1. async Task Main()
  2. {
  3. await RunAsync(File.ReadAllText(@"C:\Users\guy\source\repos\AoCMAUI\AoCService\Inputs\2024Day12.txt"), new Parts()).Dump();
  4.  
  5. async Task<(string Part1, string Part2)> RunAsync(string input, Parts parts)
  6. {
  7. (string Part1, string Part2) result = ("", "");
  8. if (parts.One) result.Part1 = FencePlotter(input, false);
  9. if (parts.Two) result.Part2 = FencePlotter(input, true);
  10. return result;
  11. }
  12.  
  13. string FencePlotter(string input, bool part2)
  14. {
  15. var lines = input.SplitLines();
  16. var xMax = lines[0].Length - 1;
  17. var yMax = lines.Count() - 1;
  18. char[,] map = new char[xMax + 1, yMax + 1];
  19. for(var i = 0; i < lines.Count(); i++)
  20. {
  21. for(var j = 0; j < lines[i].Length; j++)
  22. {
  23. map[i,j] = lines[i][j];
  24. }
  25. }
  26. var visited = new List<string>();
  27. var q = new Queue<(int i,int j, Direction d)>();
  28. var regions = new List<(char ch, int area, int perimeter)>();
  29. var regions2 = new List<(char ch, List<(int i, int j)>, int area)>();
  30. for(var i = 0; i < lines.Count(); i++)
  31. {
  32. for(var j = 0; j < lines[i].Length; j++)
  33. {
  34. if (visited.Contains($"{i}|{j}")) continue;
  35. var area = 0;
  36. var perimeter = 0;
  37. var cells = new List<(int, int)>();
  38. visited.Add($"{i}|{j}");
  39. cells.Add((i, j));
  40. var neighbours = MatchingNeighbours(i, j, map[i, j], map);
  41. foreach(var n in neighbours) q.Enqueue(n);
  42. area++;
  43. perimeter += 4 - neighbours.Count();
  44. while(q.Any())
  45. {
  46. (int i, int j, Direction d) item = q.Dequeue();
  47. if (visited.Contains($"{item.Item1}|{item.Item2}")) continue;
  48. visited.Add($"{item.Item1}|{item.Item2}");
  49. cells.Add((item.i, item.j));
  50. var ne = MatchingNeighbours(item.Item1, item.Item2, map[item.Item1, item.Item2], map);
  51. foreach(var n in ne) q.Enqueue(n);
  52. area++;
  53. perimeter += 4 - ne.Count();
  54. }
  55. regions.Add((map[i,j], area, perimeter));
  56. regions2.Add((map[i,j], cells, area));
  57. }
  58. }
  59. //map.Dump();
  60. //regions.Dump();
  61. //regions2.Dump();
  62. var totalFence = regions.Sum(r => r.perimeter * r.area);
  63. if(!part2) return $"{totalFence}";
  64. var discountFence = 0;
  65. foreach(var r2 in regions2)
  66. {
  67. var count = FindSides(r2);
  68. discountFence += count * r2.area;
  69. //$"{r2.ch}, {r2.area}, {count}".Dump();
  70. }
  71. return $"{discountFence}";
  72. }
  73.  
  74.  
  75. }
  76.  
  77. int FindSides((char ch, List<(int i, int j)> cells, int area) r2)
  78. {
  79. var edges = r2.cells.Count * 4;
  80. foreach(var cell in r2.cells)
  81. {
  82. var below = CellBelow(r2.cells, cell);
  83. var left = CellLeft(r2.cells, cell);
  84. var right = CellRight(r2.cells, cell);
  85. var above = CellAbove(r2.cells,cell);
  86. if(right)
  87. {
  88. edges--;
  89. if(!below && !CellBelow(r2.cells, (cell.i + 1, cell.j))) edges--;
  90. if(!above && !CellAbove(r2.cells, (cell.i + 1, cell.j))) edges--;
  91. }
  92. if(below)
  93. {
  94. edges--;
  95. if(!left && !CellLeft(r2.cells, (cell.i, cell.j + 1))) edges--;
  96. if(!right && !CellRight(r2.cells, (cell.i, cell.j + 1))) edges--;
  97. }
  98. if(left) edges--;
  99. if(above) edges--;
  100. }
  101.  
  102. return edges;
  103. }
  104.  
  105. bool CellBelow(List<(int i, int j)> cells, (int i, int j) cell)
  106. {
  107. return cells.Any(c => c.i == cell.i && c.j == cell.j + 1);
  108. }
  109. bool CellAbove(List<(int i, int j)> cells, (int i, int j) cell)
  110. {
  111. return cells.Any(c => c.i == cell.i && c.j == cell.j - 1);
  112. }
  113. bool CellLeft(List<(int i, int j)> cells, (int i, int j) cell)
  114. {
  115. return cells.Any(c => c.i == cell.i - 1 && c.j == cell.j);
  116. }
  117. bool CellRight(List<(int i, int j)> cells, (int i, int j) cell)
  118. {
  119. return cells.Any(c => c.i == cell.i + 1 && c.j == cell.j);
  120. }
  121.  
  122.  
  123. static List<(int i, int j, Direction d)> MatchingNeighbours(int i, int j, char ch, char[,] map)
  124. {
  125. var neighbours = new List<(int i, int j, Direction d)>();
  126. if (i > 0 && map[i - 1, j] == ch) neighbours.Add((i - 1, j, Direction.L));
  127. if (j > 0 && map[i, j - 1] == ch) neighbours.Add((i, j - 1, Direction.U));
  128. if (i < map.GetUpperBound(0) && map[i + 1, j] == ch) neighbours.Add((i + 1, j, Direction.R));
  129. if (j < map.GetUpperBound(1) && map[i, j + 1] == ch) neighbours.Add((i, j + 1, Direction.D));
  130. return neighbours;
  131. }
  132.  
  133. enum Direction
  134. {
  135. U,
  136. R,
  137. D,
  138. L
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement