diff --git a/2024/Day06/README.md b/2024/Day06/README.md new file mode 100644 index 00000000..35f96b90 --- /dev/null +++ b/2024/Day06/README.md @@ -0,0 +1,8 @@ +## --- Day 6: Guard Gallivant --- +The Historians use their fancy [device](4) again, this time to whisk you all away to the North Pole prototype suit manufacturing lab... in the year [1518](/2018/day/5)! It turns out that having direct access to history is very convenient for a group of historians. + +You still have to be careful of time paradoxes, and so it will be important to avoid anyone from 1518 while The Historians search for the Chief. Unfortunately, a single guard is patrolling this part of the lab. + +Maybe you can work out where the guard will go ahead of time so that The Historians can search safely? + +Read the [full puzzle](https://adventofcode.com/2024/day/6). diff --git a/2024/Day06/Solution.cs b/2024/Day06/Solution.cs new file mode 100644 index 00000000..0b60134d --- /dev/null +++ b/2024/Day06/Solution.cs @@ -0,0 +1,70 @@ +namespace AdventOfCode.Y2024.Day06; + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Numerics; + +using Map = System.Collections.Generic.Dictionary; + +[ProblemName("Guard Gallivant")] +class Solution : Solver { + + Complex Up = Complex.ImaginaryOne; + Complex TurnRight = -Complex.ImaginaryOne; + + public object PartOne(string input) { + var (map, start) = Parse(input); + return Walk(map, start).positions.Count(); + } + + public object PartTwo(string input) { + var (map, start) = Parse(input); + var positions = Walk(map, start).positions; + var loops = 0; + // simply try a blocker in each locations visited by the guard and count the loops + foreach (var block in positions.Where(pos => map[pos] == '.')) { + map[block] = '#'; + if (Walk(map, start).isLoop) { + loops++; + } + map[block] = '.'; + } + return loops; + } + + // returns the positions visited when starting from 'pos', isLoop is set if the + // guard enters a cycle. + (IEnumerable positions, bool isLoop) Walk(Map map, Complex pos) { + var seen = new HashSet<(Complex pos, Complex dir)>(); + var dir = Up; + while (map.ContainsKey(pos) && !seen.Contains((pos, dir))) { + seen.Add((pos, dir)); + if (map.GetValueOrDefault(pos + dir) == '#') { + dir *= TurnRight; + } else { + pos += dir; + } + } + return ( + positions: seen.Select(s => s.pos).Distinct(), + isLoop: seen.Contains((pos, dir)) + ); + } + + // store the grid in a dictionary, to make bounds checks and navigation simple + // start represents the starting postion of the guard + (Map map, Complex start) Parse(string input) { + var lines = input.Split("\n"); + var map = ( + from y in Enumerable.Range(0, lines.Length) + from x in Enumerable.Range(0, lines[0].Length) + select new KeyValuePair(-Up * y + x, lines[y][x]) + ).ToDictionary(); + + var start = map.First(x => x.Value == '^').Key; + + return (map, start); + } +} \ No newline at end of file diff --git a/2024/Day06/input.in b/2024/Day06/input.in new file mode 100644 index 00000000..6d740e90 Binary files /dev/null and b/2024/Day06/input.in differ diff --git a/2024/Day06/input.refout b/2024/Day06/input.refout new file mode 100644 index 00000000..cd63e0fc --- /dev/null +++ b/2024/Day06/input.refout @@ -0,0 +1,2 @@ +4789 +1304 \ No newline at end of file diff --git a/2024/SplashScreen.cs b/2024/SplashScreen.cs index 4efa3083..1e764cfc 100644 --- a/2024/SplashScreen.cs +++ b/2024/SplashScreen.cs @@ -8,8 +8,8 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ /* 2024 */\n \n "); - Write(0xcc00, false, " "); + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ sub y{2024}\n \n"); + Write(0xcc00, false, " "); Write(0xcccccc, false, ".--'"); Write(0xe3b585, false, "~ ~ ~"); Write(0xcccccc, false, "| .-' "); @@ -50,7 +50,7 @@ public void Show() { Write(0xcccccc, false, "|"); Write(0x427322, false, "@"); Write(0x5eabb4, false, ".."); - Write(0x488813, false, "@"); + Write(0x427322, false, "@"); Write(0xe3b585, false, "'. ~ "); Write(0xcc00, false, "\" ' "); Write(0xe3b585, false, "~ "); @@ -69,8 +69,8 @@ public void Show() { Write(0xcccccc, false, "|"); Write(0x4d8b03, false, "_"); Write(0x5eabb4, false, ".~."); - Write(0x1461f, false, "_"); - Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "_"); + Write(0x488813, false, "#"); Write(0xe3b585, false, "'.. ~ ~ "); Write(0xffff66, true, "*"); Write(0xcccccc, false, "| | "); @@ -81,20 +81,32 @@ public void Show() { Write(0xffff66, true, "* "); Write(0xcccccc, false, "| 5 "); Write(0xffff66, false, "**\n "); - Write(0x333333, false, "| | | .' '. | "); - Write(0x666666, false, " 6\n 7\n "); - Write(0x666666, false, " 8\n 9\n "); - Write(0x666666, false, " 10\n "); - Write(0x666666, false, " 11\n 12\n "); - Write(0x666666, false, " 13\n "); - Write(0x666666, false, " 14\n 15\n "); - Write(0x666666, false, " 16\n "); - Write(0x666666, false, " 17\n 18\n "); - Write(0x666666, false, " 19\n "); - Write(0x666666, false, " 20\n 21\n "); - Write(0x666666, false, " 22\n "); - Write(0x666666, false, " 23\n 24\n "); - Write(0x666666, false, " 25\n \n"); + Write(0xcccccc, false, "| "); + Write(0xffffff, false, "||| "); + Write(0x427322, false, "@"); + Write(0x488813, false, "@@@"); + Write(0xe3b585, false, "'''..."); + Write(0xcccccc, false, "| |"); + Write(0xa25151, false, "... "); + Write(0xcccccc, false, ".' '."); + Write(0xcc00, false, "'''.."); + Write(0xd4dde4, false, "/"); + Write(0xcc00, false, ".."); + Write(0xcccccc, false, "| 6 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, "| | | | | | "); + Write(0x666666, false, " 7\n 8\n "); + Write(0x666666, false, " 9\n 10\n "); + Write(0x666666, false, " 11\n "); + Write(0x666666, false, " 12\n 13\n "); + Write(0x666666, false, " 14\n "); + Write(0x666666, false, " 15\n 16\n "); + Write(0x666666, false, " 17\n "); + Write(0x666666, false, " 18\n 19\n "); + Write(0x666666, false, " 20\n "); + Write(0x666666, false, " 21\n 22\n "); + Write(0x666666, false, " 23\n "); + Write(0x666666, false, " 24\n 25\n \n"); Console.ForegroundColor = color; Console.WriteLine(); diff --git a/2024/calendar.svg b/2024/calendar.svg index 952e3d1c..b6ef689d 100644 --- a/2024/calendar.svg +++ b/2024/calendar.svg @@ -1,4 +1,4 @@ - +