From bba775fd4ef3ec4886fae44ee48740c345e47832 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sun, 9 Feb 2025 14:21:48 -0500 Subject: [PATCH] wip day 12 --- .../Problems/AOC2024/Day12/GardenGroups.cs | 106 +++++++++++++++--- AdventOfCode/Utils/Models/Common.cs | 4 + 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/AdventOfCode/Problems/AOC2024/Day12/GardenGroups.cs b/AdventOfCode/Problems/AOC2024/Day12/GardenGroups.cs index fa4c455..a80e65a 100644 --- a/AdventOfCode/Problems/AOC2024/Day12/GardenGroups.cs +++ b/AdventOfCode/Problems/AOC2024/Day12/GardenGroups.cs @@ -1,6 +1,7 @@ using AdventOfCode.Utils.Models; using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; using System.Text; @@ -31,17 +32,18 @@ internal class GardenGroups : Problem public override void CalculatePart2() { var plots = FindPlots(_data); - var r = plots.Select(plot => (plot.plant, area: plot.area.Count, sides: CountSides(GroupSides(plot.outline), plot.area))); - foreach (var item in plots) + var r = plots.Select(plot => (plot.plant, area: plot.area.Count, sides: CountSides(GroupSides(plot.outline, plot.area), plot.area))); + foreach (var (plant, area, perimeter, outline) in plots) { - Console.WriteLine($"{item.plant}: {CountSides(GroupSides(item.outline), item.area)}"); - var groups = GroupSides(item.outline); - DrawPlot(item.area, groups, item.plant); + Console.WriteLine(); + var groups = GroupSides(outline, area); + Console.WriteLine($"{plant}: {CountSides(groups, area)}, {groups.Count}"); + DrawPlot(area, groups, plant); } Part2 = r.Sum(v => v.area * v.sides); } - public static List>> GroupSides(List> outline) + public static List>> GroupSides(List> outline, List> area) { var result = new List>>(); var visited = new HashSet>(); @@ -51,6 +53,9 @@ internal class GardenGroups : Problem { var p = open.First(); open.Remove(p); + if(visited.Contains(p)) + continue; + visited.Add(p); var group = new List>() { p }; GetGroup(p, group); result.Add(group); @@ -58,7 +63,30 @@ internal class GardenGroups : Problem void GetGroup(Vec2 point, List> group) { - throw new NotImplementedException(); + var up = DIRS[0]; + var right = DIRS[1]; + if(outline.Contains(point + up) || outline.Contains(point - up)) + { + ProcessDirection(point, up, group); + ProcessDirection(point, -up, group); + } + else if(outline.Contains(point + right) || outline.Contains(point - right)) + { + ProcessDirection(point, right, group); + ProcessDirection(point, -right, group); + } + } + + void ProcessDirection(Vec2 point, Vec2 dir, List> group) + { + var n = point + dir; + if (!outline.Contains(n) || visited.Contains(n)) + return; + //if (!area.Contains(n + dir.YX) && !area.Contains(n - dir.YX)) + // return; + visited.Add(n); + group.Add(n); + ProcessDirection(n, dir, group); } return result; @@ -69,13 +97,30 @@ internal class GardenGroups : Problem { var (min, max) = GetBounds(outline.SelectMany(v => v).ToList()); + int Sides(Vec2 point, List> group) + { + var s = 0; + foreach (var dir in DIRS) + { + var n = point + dir; + if (area.Contains(n)) + s++; + if(group.Count > 1 && outline.Any(g => group != g && g.Contains(n))) + s--; + } + return s; + } + ConsoleColor[] colors = [ ConsoleColor.Red, - ConsoleColor.Green, + ConsoleColor.DarkGreen, ConsoleColor.Blue, - ConsoleColor.Yellow, + ConsoleColor.DarkRed, ConsoleColor.Magenta, - ConsoleColor.Cyan, + ConsoleColor.DarkCyan, + ConsoleColor.DarkBlue, + ConsoleColor.DarkMagenta, + ConsoleColor.DarkYellow ]; for (int y = min.Y; y <= max.Y; y++) @@ -86,22 +131,27 @@ internal class GardenGroups : Problem var p = new Vec2(x,y); if (area.Contains(p)) { - Console.BackgroundColor = ConsoleColor.DarkGreen; + Console.BackgroundColor = ConsoleColor.Black; Console.Write(plant); } else { - var match = outline.FirstOrDefault(v => v.Contains(p)); - if (match != null) + var curSideGroup = outline.FirstOrDefault(v => v.Contains(p)); + if (curSideGroup != null) { - var idx = outline.IndexOf(match); + var idx = outline.IndexOf(curSideGroup); Console.BackgroundColor = colors[idx % colors.Length]; - Console.Write(' '); + var s = Sides(p, curSideGroup); + if(curSideGroup.Count > 1 && IsInclosed(curSideGroup, outline, area)) + Console.Write('&'); + else + Console.Write(s); }else Console.Write(' '); } Console.ResetColor(); } + Console.ResetColor(); Console.WriteLine(); } Console.ResetColor(); @@ -147,9 +197,28 @@ internal class GardenGroups : Problem return (min, max); } + public static bool IsInclosed(List> side, List>> sides, List> area) + { + var otherSides = sides.Where(g => g != side).SelectMany(s => s).ToFrozenSet(); + foreach (var point in side) + { + foreach (var dir in DIRS) + { + var n = point + dir; + if (side.Contains(n)) + continue; + if (!area.Contains(n)) + return false; + if (otherSides.Contains(n)) + return false; + } + } + return true; + } + public static int CountSides(List>> groups, List> area) { - int Sides(Vec2 point) + int Sides(Vec2 point, List> group) { var s = 0; foreach (var dir in DIRS) @@ -157,11 +226,12 @@ internal class GardenGroups : Problem var n = point + dir; if(area.Contains(n)) s++; + if (group.Count > 1 && groups.Any(g => group != g && g.Contains(n))) + s--; } return s; } - - return groups.Sum(s => s.Select(Sides).Max()); + return groups.Sum(s => s.Select(p => Sides(p, s)).Max() + (s.Count > 1 && IsInclosed(s, groups, area) ? 1 : 0)); } private static List<(char plant, List> area, int perimeter, List> outline)> FindPlots(char[][] data) diff --git a/AdventOfCode/Utils/Models/Common.cs b/AdventOfCode/Utils/Models/Common.cs index 6ec5e27..7183ef1 100644 --- a/AdventOfCode/Utils/Models/Common.cs +++ b/AdventOfCode/Utils/Models/Common.cs @@ -6,6 +6,10 @@ public record struct Vec2(T X, T Y) where T : INumber { public static Vec2 Zero => new (T.Zero, T.Zero); public static Vec2 One => new (T.One, T.One); + + public readonly Vec2 YX => new(Y, X); + public readonly Vec2 YY => new(Y, Y); + public readonly Vec2 XX => new(X, X); public static Vec2 Splat(T v) => new(v, v); public static Vec2 operator +(Vec2 left, Vec2 right) => new Vec2(left.X + right.X, left.Y + right.Y); public static Vec2 operator -(Vec2 left, Vec2 right) => new Vec2(left.X - right.X, left.Y - right.Y);