diff --git a/Solutions/2024/Day14.cs b/Solutions/2024/Day14.cs index 26555c9..9901b3b 100644 --- a/Solutions/2024/Day14.cs +++ b/Solutions/2024/Day14.cs @@ -12,6 +12,7 @@ public static partial class Day14 { [Init] public static void LoadRobots(string[] input) => _robots = [.. input.As()]; + public static int Part1(string[] _, Action? visualise = null, params object[]? args) { const int NO_OF_SECONDS = 100; @@ -20,12 +21,12 @@ public static int Part1(string[] _, Action? visualise = null, pa int height = args.TilesTall(); List robots = [.. _robots]; - + robots.VisualiseMap(width, height, "Initial state:", visualise); for (int noOfSeconds = 1; noOfSeconds <= NO_OF_SECONDS; noOfSeconds++) { robots = [.. robots.Select(r => r.MoveNext(width, height))]; - if (noOfSeconds < 6) { + if (noOfSeconds < 6 && height < 50) { robots.VisualiseMap(width, height, $"After {noOfSeconds} seconds:", visualise); } } @@ -35,50 +36,92 @@ public static int Part1(string[] _, Action? visualise = null, pa return robots.SafetyFactor(width, height); } - public static string Part2(string[] input, params object[]? args) => NO_SOLUTION_WRITTEN_MESSAGE; - private static Robot MoveNext(this Robot robot, int width, int height) { (int x, int y) = (robot.Position + robot.Velocity); - if (x >= width ) { x %= width; } - if (y >= height) { y %= height; } - if (x < 0) { x = width + x; } - if (y < 0) { y = height + y; } + + //if (x >= width ) { x %= width; } + //if (y >= height) { y %= height; } + //if (x < 0) { x = width + x; } + //if (y < 0) { y = height + y; } + + x = x < 0 ? width + x : x % width; + y = y < 0 ? height + y : y % height; return robot with { Position = new(x, y) }; } public static int SafetyFactor(this IEnumerable robots, int width, int height) { - int midX = width / 2; + int midX = width / 2; int midY = height / 2; - int quad1 = robots.Count(robot => robot.Position.X < midX && robot.Position.Y < midY); - int quad2 = robots.Count(robot => robot.Position.X > midX && robot.Position.Y < midY); - int quad3 = robots.Count(robot => robot.Position.X < midX && robot.Position.Y > midY); - int quad4 = robots.Count(robot => robot.Position.X > midX && robot.Position.Y > midY); + int quad1 = robots.Count(robot => robot.Position.X < midX && robot.Position.Y < midY); + int quad2 = robots.Count(robot => robot.Position.X > midX && robot.Position.Y < midY); + int quad3 = robots.Count(robot => robot.Position.X < midX && robot.Position.Y > midY); + int quad4 = robots.Count(robot => robot.Position.X > midX && robot.Position.Y > midY); return quad1 * quad2 * quad3 * quad4; + } + + + public static int Part2(string[] _, Action? visualise = null, params object[]? args) + { + int width = args.TilesWide(); + int height = args.TilesTall(); + + List robots = [.. _robots]; + + int noOfSeconds = 0; + for (noOfSeconds = 0; !robots.IsChristmasTree(width, height); noOfSeconds++) { + robots = [.. robots.Select(r => r.MoveNext(width, height))]; + } + + robots.VisualiseMap(width, height, "Christmas Tree:", visualise); + return noOfSeconds; } - public static void VisualiseMap(this IEnumerable robots, int width, int height, string title, Action? visualise) + public static bool IsChristmasTree(this IEnumerable robots, int width, int _) { - const char EMPTY = '.'; + int midX = width / 2; + int count = 0; + int prevX = 0; + foreach (Robot robot in robots.OrderBy(robots => robots.Position.Y).ThenBy(robots => robots.Position.X)) { + if (robot.Position.X == prevX + 1 ) { + count++; + if (count > 10) { + return true; + } + } else { + count = 0; + } + + prevX = robot.Position.X; + } + + return false; + } + + public static void VisualiseMap(this IEnumerable robots, int width, int height, string title, Action? visualise) + { int[,] map = new int[width, height]; - //map = map.Fill(0); foreach (Robot robot in robots) { map[robot.Position.X, robot.Position.Y] += 1; } if (visualise is not null) { - string[] output = ["", title, .. map.AsStrings().Select(s => s.Replace('0', EMPTY))]; + string[] output = ["", title, .. map.AsStrings().Select(s => s.Replace('0', '.'))]; _ = Task.Run(() => visualise?.Invoke(output, false)); } } + private static int TilesWide(this object[]? args) => GetArgument(args, 1, 101); + private static int TilesTall(this object[]? args) => GetArgument(args, 2, 103); + + public sealed record Robot(Point Position, Point Velocity) : IParsable { public static Robot Parse(string s, IFormatProvider? provider) @@ -97,8 +140,4 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov [GeneratedRegex("""p=(?[\+\-]?\d+),(?[\+\-]?\d+) v=(?[\+\-]?\d+),(?[\+\-]?\d+)""")] public static partial Regex InputRegEx(); - - private static int TilesWide(this object[]? args) => GetArgument(args, 1, 101); - private static int TilesTall(this object[]? args) => GetArgument(args, 2, 103); - }