From f0240e785ac10a3b5b5c7a83b3e55c838086cbfa Mon Sep 17 00:00:00 2001 From: Parnic Date: Sat, 24 Dec 2022 12:53:56 -0600 Subject: [PATCH] Day 24 solution This is super slow, but it works. Talked through some speedup ideas with @tocchan that I'm going to try next. Gonna be a BFS pro by the end of this advent... --- advent-of-code-2022.csproj | 2 + inputs/24.txt | 292 +++++-------------------------------- inputs/24a.txt | 7 + inputs/24b.txt | 6 + src/24.cs | 260 +++++++++++++++++++++++++++++++++ 5 files changed, 312 insertions(+), 255 deletions(-) create mode 100644 inputs/24a.txt create mode 100644 inputs/24b.txt create mode 100644 src/24.cs diff --git a/advent-of-code-2022.csproj b/advent-of-code-2022.csproj index 3dd7e3a..ca04e48 100644 --- a/advent-of-code-2022.csproj +++ b/advent-of-code-2022.csproj @@ -95,6 +95,8 @@ + + diff --git a/inputs/24.txt b/inputs/24.txt index 78fe59a..abfb30d 100644 --- a/inputs/24.txt +++ b/inputs/24.txt @@ -1,255 +1,37 @@ -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 11 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 6 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 13 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 14 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 14 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -8 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 10 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 13 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 9 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 12 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -11 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 8 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -4 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 13 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 12 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 6 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 9 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -1 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 15 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -8 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 4 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 10 -mul y x -add z y - - 101011000001011100001001101 -10001011110100101011011101110101 \ No newline at end of file +#.#################################################################################################### +#v><>>>v>v^<<<^><^>>^..>^^^>^><<.<^<^v<<.v^>^vv.^v^>^>.^>^<v>v>>v><^..^.^v..^v^># +#>>>.^^>>^^>^>><<<<^v><.<>>.v.vvv<>v<>><^^^># +#>.v.<>>vvv^.>^v<^^^.^.><^vv>^..>^>>>><^^v>^v^>v<<>>.^>^^^>>vv>v>..^>..v<<<<# +#<^>v>>^<<^^<^^^^<.<....>v..^v<.v^<<>>^^>.<^^>><>^<.>vv.^<^^^.v<^>v^^^># +#>vv^<^.^^^.^.><<<^vv>^<^<>v>>^^^.v<>><>vv.v.<<>>><<^><<.><><<>^v^<>v>^vv>^><>.v>.<# +#<^^v<>^<<<.v<v.>^v^^^^>v><^>v<^^.v^^v<>v.>><.<<^^>>.^<>>v^^v<.><<>v>^^^v>v^>^<>.<.^^v^v^.v>>>v>.^.vv<^^^>^<>>.<^<><<>^^vv><<<><^v>>^>v>v>^<>v^v<><# +#<>><><^><.v^v^>><>v>^>.<.>>.v<^v^v.^<<<.v^.<>>.^v<..^.v^.v^v^^^>>^vvv.<.^<<>.<<># +#><>>vv^v^.>v^^v<<.>v<^><^v>>.^v>><>^.>><^<>^>^>v>^>^^.>><^>^..<^<><^^<^><><<.>.<.<# +#>^>v^v>v<^v>>^vv^v.>^.vv^>>^<^>^^vvv^>v^^^><.>><>^.v<^<<<.v<<<<<>.v>>^>^vv>^^^^>^><^v^^.# +#>^v<>v><.vv^^>>.>v^>>^.>>^><<^<>>v^><>.^v.v^^>v><^v<><^.^vv.vv.v>.v<^^>>vv<>^^v^>^># +#<<>vv<.>v.<<^<>v>.^..<^><<>>v>^>v<>v^<>.vv>v>>^.>>>>v<^^.>^^<.<^v^>.v^v<^<.<<# +#>>vv>^.^<^.v><>>vv<.^<>.<.v.v>v^<>^<^v.^<><<>^^^.><>vv>><.^v^^<^v<^vv>>v^<># +#>^>>v<^<<^>><<^.^>>>v^>vv<<<><^^>>>>>.v.^^>^>^^>.^<>><^<^<.>.^^^<^vvvv<>># +#>.>>>v^>>>^.^<^>^.v.^.^><^><^^v.v<<<>>>v>v^v^>v^<>^>v<<^>v^^><<<>v^v.^^.^.v>vv>.^>v>v<># +#>v<>^<^.<<>vv^>>^^<<^^>v><><<^><<>v<<<^^^>v>>v.v><<^^^<^v^^>>^><<>>v>><.>.>v>>><# +#^<.^>v<^v><^^>v.<^<^v^^.>^v>v^>v^^>><>>^>.<>^v>>.<<<^<^v^<^v<# +#>.>v>><.<^<.^>v>.v>^^<<^>v<^<.<>vv^v>>.v<^><<.<<><>>>>^<<<^.>><>vv<><^><># +#>v>vv<<^<^><^<>>><^>v>.^<>vv<>v<^.<^<><<.<>v><>><^><<^v<.^<^>^^v^v>># +#>v^v.v.><.^>v>vv<>...>^.>^.>>>^^><^>.<><<^.^.vvv^v^v>.^<<vv><.<# +#>.^.^><^<.<>v><.><><.>>>>v^vv^>v><^<.>^>v>^>v^^><^^<^># +#^^v.^^..vv>>vv>><^^>v^>v<.<><>.^>v^vv.^.^<..v><.^v^^<>>^^>.<<># +#>v^<v<^v>v><^>v>v<>vv>^v<>^v<<<^vvv<<^<>^v^>># +#>>>v<^>>v>.<><<<>.>.^vv<>vv^.^vv>^vv.v<.vv>v>>>>..vv^<^>^^...^vv^vv>>^v^<# +#>v>.vvv<>v^.^<v^.>v<^vv.<^<v^^^>^><<.^^^^v>vv<<<>.v^>>v>v<>v><^vv.<<^>^v>^^>v<># +#<.<>^.<v<>v>>>.><<<>.^<^vv<.^<.vv<>vv<^>^<.>vvv<^<<<><^.<# +#>^vv<.><<^><^>>^^>v>>v.v.^>v>^<^>><^v>.vvvv<>v>^^>vv.<>v>^<<<^.v^v^^^^>^.vv..^^>.>>^><^>v^v>^># +#>^<.><^<>v^<<>^^>v>^>vv^><.v^<>>^v.>^v^<>.v^v<.^>^^v.v<>v<^>>^^>^vv.>^v<<.^><^<^^vv>>vvv^^v..# +#.<^<<>^v.<<.<^vvv>vv>.v>vv<^<<<<^vv>vv<^<.^>^.^>v<<>^>v^^^>^>.<>^v<^<>vv<><><^.^v.>>>.<^>>^>^>v^^^.^<.<>vv>^<>><>v>^>.v<>v^>^>v.v.>^v<# +#>v^>^>v^.vv<.^>v.vv>.^>^>^^><<^^v<>v<^vv><>^^^<<<><<>^<.>.vv^>vv<<<<vvv># +#>vv<<<^v<>>v^..v.<<^v<<<<^.<<<<^>>v.<^^<<^v>v^><.>v<^>>^.v^vv<<>^^vv>^>v>>v># +#>>.^v>>v^v^>^^.v^v>^v>>>>>vv>>^>^v><>^^>>>vv>v>^>vv.^v>vv>.>^v# +#<^<^.>.>>v.<<>v>^.v^<<><><>^v^v<>^<>>.vv<<^v<<>^^v^^^>>.<<^^v<^>v>.v>vv>><<# +#><>>v.<<>.>.>^^^^^vvv><><<>>>v^v.^.><>><.^<>..><>^.><<.^^>v>^.>>>v>># +####################################################################################################.# \ No newline at end of file diff --git a/inputs/24a.txt b/inputs/24a.txt new file mode 100644 index 0000000..d29db5e --- /dev/null +++ b/inputs/24a.txt @@ -0,0 +1,7 @@ +#.##### +#.....# +#>....# +#.....# +#...v.# +#.....# +#####.# \ No newline at end of file diff --git a/inputs/24b.txt b/inputs/24b.txt new file mode 100644 index 0000000..b42829a --- /dev/null +++ b/inputs/24b.txt @@ -0,0 +1,6 @@ +#.###### +#>>.<^<# +#.<..<<# +#>v.><># +#<^v^^># +######.# \ No newline at end of file diff --git a/src/24.cs b/src/24.cs new file mode 100644 index 0000000..be7ad35 --- /dev/null +++ b/src/24.cs @@ -0,0 +1,260 @@ +using aoc2022.Util; + +namespace aoc2022; + +internal class Day24 : Day +{ + private enum cellType + { + open = 0, + wall = 1 << 0, + blizUp = 1 << 1, + blizRight = 1 << 2, + blizDown = 1 << 3, + blizLeft = 1 << 4, + } + + private int[][]? grid; + internal override void Parse() + { + var lines = new List(Util.Parsing.ReadAllLines($"{GetDayNum()}")); + grid = new int[lines.Count][]; + for (int row = 0; row < lines.Count; row++) + { + var line = lines[row]; + grid[row] = new int[line.Length]; + for (int col = 0; col < line.Length; col++) + { + grid[row][col] = line[col] switch + { + '#' => (int)cellType.wall, + '.' => (int)cellType.open, + '^' => (int)cellType.blizUp, + '>' => (int)cellType.blizRight, + 'v' => (int)cellType.blizDown, + '<' => (int)cellType.blizLeft, + _ => throw new Exception(), + }; + } + } + } + + private static int[][] deepCopyGrid(int[][] src) + { + var copy = (int[][])src.Clone(); + for (int i = 0; i < src.Length; i++) + { + copy[i] = (int[])src[i].Clone(); + } + + return copy; + } + + private static void render(string label, int[][] grid) + { + Console.WriteLine(label); + + for (int row = 0; row < grid.Length; row++) + { + for (int col = 0; col < grid[row].Length; col++) + { + if (grid[row][col] == (int) cellType.wall) + { + Console.Write('#'); + } + else if (grid[row][col] == (int) cellType.open) + { + Console.Write('.'); + } + else if (grid[row][col] == (int) cellType.blizRight) + { + Console.Write('>'); + } + else if (grid[row][col] == (int) cellType.blizLeft) + { + Console.Write('<'); + } + else if (grid[row][col] == (int) cellType.blizUp) + { + Console.Write('^'); + } + else if (grid[row][col] == (int) cellType.blizDown) + { + Console.Write('v'); + } + else + { + int numSet = 0; + var enumVals = Enum.GetValues(); + for (int i = 2; i < enumVals.Length; i++) + { + if ((grid[row][col] & (int)enumVals[i]) != 0) + { + numSet++; + } + } + Console.Write($"{numSet}"); + } + } + + Console.WriteLine(); + } + + Console.WriteLine(); + } + + private static int[][] advanceSim(int[][] grid) + { + var next = deepCopyGrid(grid); + for (int row = 1; row < grid.Length - 1; row++) + { + for (int col = 0; col < grid[row].Length; col++) + { + if (grid[row][col] == (int)cellType.wall) + { + continue; + } + + if (grid[row][col] == (int)cellType.open) + { + continue; + } + + var isRight = (grid[row][col] & (int) cellType.blizRight) != 0; + var isLeft = (grid[row][col] & (int) cellType.blizLeft) != 0; + var isUp = (grid[row][col] & (int) cellType.blizUp) != 0; + var isDown = (grid[row][col] & (int) cellType.blizDown) != 0; + if (isRight) + { + var nextCol = col + 1; + if (grid[row][nextCol] == (int) cellType.wall) + { + nextCol = 1; + } + + next[row][col] -= (int) cellType.blizRight; + next[row][nextCol] += (int) cellType.blizRight; + } + if (isLeft) + { + var nextCol = col - 1; + if (grid[row][nextCol] == (int) cellType.wall) + { + nextCol = grid[row].Length - 2; + } + + next[row][col] -= (int) cellType.blizLeft; + next[row][nextCol] += (int) cellType.blizLeft; + } + if (isUp) + { + var nextRow = row - 1; + if (grid[nextRow][col] == (int) cellType.wall) + { + nextRow = grid.Length - 2; + } + + next[row][col] -= (int) cellType.blizUp; + next[nextRow][col] += (int) cellType.blizUp; + } + if (isDown) + { + var nextRow = row + 1; + if (grid[nextRow][col] == (int) cellType.wall) + { + nextRow = 1; + } + + next[row][col] -= (int) cellType.blizDown; + next[nextRow][col] += (int) cellType.blizDown; + } + } + } + + return next; + } + + private static (int steps, int[][] gridState) getMinSteps(int[][] grid, ivec2 start, ivec2 dest) + { + Queue<(ivec2 pos, int[][] gridState, int steps)> states = new(); + states.Enqueue((start, deepCopyGrid(grid), 0)); + + int? minSteps = null; + int[][]? minGridState = null; + + // render("Start:", p1grid); + while (states.TryDequeue(out var q)) + { + if (minSteps != null && q.steps > minSteps) + { + continue; + } + + var next = advanceSim(q.gridState); + // check if we can wait + if (next[q.pos.y][q.pos.x] == (int) cellType.open) + { + var nextState = (pos: q.pos, next: next, steps: q.steps + 1); + if (!states.Any(s => s.pos == nextState.pos && s.steps == nextState.steps)) + { + states.Enqueue(nextState); + } + } + + // queue up all neighbor possibilities + foreach (var n in q.pos.GetOrthogonalNeighbors()) + { + if (n == dest) + { + if (minSteps == null || q.steps + 1 < minSteps) + { + minSteps = q.steps + 1; + minGridState = next; + } + + continue; + } + + if (n.x < 0 || n.y < 0 || n.x >= next[0].Length || n.y >= next.Length) + { + continue; + } + + if (next[n.y][n.x] == (int) cellType.open) + { + var nextState = (pos: n, next: next, steps: q.steps + 1); + if (!states.Any(s => s.pos == nextState.pos && s.steps == nextState.steps)) + { + states.Enqueue(nextState); + } + } + } + + // render($"After {i+1} minute{(i + 1 == 1 ? "" : "s")}:", p1grid); + } + + return (minSteps!.Value, minGridState!); + } + + internal override string Part1() + { + var start = new ivec2(1, 0); + var dest = new ivec2(grid![0].Length - 2, grid!.Length - 1); + + var (minSteps, _) = getMinSteps(grid!, start, dest); + + return $"Minimum steps to reach the end: <+white>{minSteps}"; + } + + internal override string Part2() + { + var start = new ivec2(1, 0); + var dest = new ivec2(grid![0].Length - 2, grid!.Length - 1); + + var toEndOnce = getMinSteps(grid!, start, dest); + var backToStart = getMinSteps(toEndOnce.gridState, dest, start); + var toEndAgain = getMinSteps(backToStart.gridState, start, dest); + + return $"Minimum steps to go there and back again: <+white>{toEndOnce.steps + backToStart.steps + toEndAgain.steps}"; + } +}