Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- async Task Main()
- {
- await RunAsync(File.ReadAllText(@"C:\Users\guy\source\repos\AoCMAUI\AoCService\Inputs\2024Day12.txt"), new Parts()).Dump();
- async Task<(string Part1, string Part2)> RunAsync(string input, Parts parts)
- {
- (string Part1, string Part2) result = ("", "");
- if (parts.One) result.Part1 = FencePlotter(input, false);
- if (parts.Two) result.Part2 = FencePlotter(input, true);
- return result;
- }
- string FencePlotter(string input, bool part2)
- {
- var lines = input.SplitLines();
- var xMax = lines[0].Length - 1;
- var yMax = lines.Count() - 1;
- char[,] map = new char[xMax + 1, yMax + 1];
- for(var i = 0; i < lines.Count(); i++)
- {
- for(var j = 0; j < lines[i].Length; j++)
- {
- map[i,j] = lines[i][j];
- }
- }
- var visited = new List<string>();
- var q = new Queue<(int i,int j, Direction d)>();
- var regions = new List<(char ch, int area, int perimeter)>();
- var regions2 = new List<(char ch, List<(int i, int j)>, int area)>();
- for(var i = 0; i < lines.Count(); i++)
- {
- for(var j = 0; j < lines[i].Length; j++)
- {
- if (visited.Contains($"{i}|{j}")) continue;
- var area = 0;
- var perimeter = 0;
- var cells = new List<(int, int)>();
- visited.Add($"{i}|{j}");
- cells.Add((i, j));
- var neighbours = MatchingNeighbours(i, j, map[i, j], map);
- foreach(var n in neighbours) q.Enqueue(n);
- area++;
- perimeter += 4 - neighbours.Count();
- while(q.Any())
- {
- (int i, int j, Direction d) item = q.Dequeue();
- if (visited.Contains($"{item.Item1}|{item.Item2}")) continue;
- visited.Add($"{item.Item1}|{item.Item2}");
- cells.Add((item.i, item.j));
- var ne = MatchingNeighbours(item.Item1, item.Item2, map[item.Item1, item.Item2], map);
- foreach(var n in ne) q.Enqueue(n);
- area++;
- perimeter += 4 - ne.Count();
- }
- regions.Add((map[i,j], area, perimeter));
- regions2.Add((map[i,j], cells, area));
- }
- }
- //map.Dump();
- //regions.Dump();
- //regions2.Dump();
- var totalFence = regions.Sum(r => r.perimeter * r.area);
- if(!part2) return $"{totalFence}";
- var discountFence = 0;
- foreach(var r2 in regions2)
- {
- var count = FindSides(r2);
- discountFence += count * r2.area;
- //$"{r2.ch}, {r2.area}, {count}".Dump();
- }
- return $"{discountFence}";
- }
- }
- int FindSides((char ch, List<(int i, int j)> cells, int area) r2)
- {
- var edges = r2.cells.Count * 4;
- foreach(var cell in r2.cells)
- {
- var below = CellBelow(r2.cells, cell);
- var left = CellLeft(r2.cells, cell);
- var right = CellRight(r2.cells, cell);
- var above = CellAbove(r2.cells,cell);
- if(right)
- {
- edges--;
- if(!below && !CellBelow(r2.cells, (cell.i + 1, cell.j))) edges--;
- if(!above && !CellAbove(r2.cells, (cell.i + 1, cell.j))) edges--;
- }
- if(below)
- {
- edges--;
- if(!left && !CellLeft(r2.cells, (cell.i, cell.j + 1))) edges--;
- if(!right && !CellRight(r2.cells, (cell.i, cell.j + 1))) edges--;
- }
- if(left) edges--;
- if(above) edges--;
- }
- return edges;
- }
- bool CellBelow(List<(int i, int j)> cells, (int i, int j) cell)
- {
- return cells.Any(c => c.i == cell.i && c.j == cell.j + 1);
- }
- bool CellAbove(List<(int i, int j)> cells, (int i, int j) cell)
- {
- return cells.Any(c => c.i == cell.i && c.j == cell.j - 1);
- }
- bool CellLeft(List<(int i, int j)> cells, (int i, int j) cell)
- {
- return cells.Any(c => c.i == cell.i - 1 && c.j == cell.j);
- }
- bool CellRight(List<(int i, int j)> cells, (int i, int j) cell)
- {
- return cells.Any(c => c.i == cell.i + 1 && c.j == cell.j);
- }
- static List<(int i, int j, Direction d)> MatchingNeighbours(int i, int j, char ch, char[,] map)
- {
- var neighbours = new List<(int i, int j, Direction d)>();
- if (i > 0 && map[i - 1, j] == ch) neighbours.Add((i - 1, j, Direction.L));
- if (j > 0 && map[i, j - 1] == ch) neighbours.Add((i, j - 1, Direction.U));
- if (i < map.GetUpperBound(0) && map[i + 1, j] == ch) neighbours.Add((i + 1, j, Direction.R));
- if (j < map.GetUpperBound(1) && map[i, j + 1] == ch) neighbours.Add((i, j + 1, Direction.D));
- return neighbours;
- }
- enum Direction
- {
- U,
- R,
- D,
- L
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement