diff --git a/2022/day24/input b/2022/day24/input new file mode 100644 index 0000000..0211afa --- /dev/null +++ b/2022/day24/input @@ -0,0 +1,37 @@ +#.#################################################################################################### +#<>^^^>v.<<^.v>^v>v>>vv<.>>>^^v>^.><^>>v<>>>>v^^^.v^v<>^^v><^vvv<^v>><<^.<<^>^<># +#>^v<^^>.<<^>>>^^>v>^^>v>^><^>^>vv^>vv>.^^<>.>>vv<^>.<v<^># +#.^<.>v^>.>>>.<>^>^^v^<<^<>v>>vv^<..vv>><<..v>>.v><^>v>^>^>^^><.<^<>>vv># +#>v^<<^v>vv<<.>>^<<<><>v>vv.<>v^vv<>v^^.<>vvv>^<<<>v^><>v<^.^^^.<>^v>>.v<<<^v<>.^v<>>vv<^v^><# +#.<><<>vv>><>.><<.>><>v>v^v^vv>.^^v>>>^v.><>>>>v^v^<^.v>^v>><<^<>^v>..<<>^^<>><.<^v^v.^><># +#><..v^v><<<<<>.<>v<<^^v>^^vvv^v^<<><.v><..>vv^v<<^<^^^># +#<>^>^>.v<>>v^^v>^>v^>.>><<>vv^^v>>v><^v><<>>>^.^.^^<.^>.><<<^v^>v..^^>^v<^.# +#>^^.v^v<>.>><>vv>.<>><>>><<>v><.v<^^^<>v>^v><^^<^.v.>>>v>v.vv>v>>v^.>.^>v^^<>>v>^v^<.v>^.>v><^># +#<^<<>..<>.vvv>>^.vv<>><>^<<>v.<.^v>v>^><>^^<><>^^.vv.>^v>^^v<><># +#><.>^v><>..v>vv<^<>>^.^v<^vv<^>>^vvvv>^^>>^^><# +#<^<>vvv>^.>v>>.><>>^.>v<>v^v^<^<^^><>>v^><^>.^v^v<^^v><>>v^^<<>>^><<<^v><>^^^.v<# +#.^^.>v.>^.v<^.^.^vv^<>>.v>^<>v>^v><^v>vvv^^^<>^<>^>vv>vvv.<>vv>^<.v>.<>.vv<>>.>vvv<># +#<^^<.^>>v><><^v<.<.><v>>v>v^.<.v<.v.v<.>><^>^v<<^^<^^^.^.>>.v>^><<^>^.>^v^^>v^v<>^>^<.>.><# +#<.^v>>>.v<<<^.v.>v^^<^>v<^v^v^.^<>>^v>^v.^><^.v>><>vvv^^<<^>.^vv.^v.vv<..<# +#.v^v>>v^vv^v>v.vv>^<<..v<<>>vv^<<^^<<<<^>v>vv^<^v^vv><.^^>v^>^>^>^v># +#<>.>^vv<>v^^><>><^^>v<<^^>^>.^^<.v><>v^^v>>^>>.>>.<>vv><^^<^<<>><^vv>>v>^^.^><.^v^<^<><<^vv>>>.v<>^v^^<<><>v>^v^v>^^^vvv>>v^>>v>><>><>>^..v<>><^v^>><.>^<<# +#>^^<^>.<^>>>v<vv^^><vvvv^>^>vv<^<.v<<<>>^v>>..>^.># +#>>v>^<.>.v^>>>.>v.vv^>^>v>^<>^.^^^^>><>..^.>v>^v.v.^<><<><>><# +#<>v>>.v>.^>^<<><^v<.>^vv.>^..>v<<^^>^>>vv<>^v.<^v<^>><<<<^^v^v<<^^v.<>^vvv>^><<>^>^<# +#<><^><^.v<>^vv>v>^>^^<.>^^^^vv<>v<^.vvv.^v^>>^.v>>.>v^v<.><>.>>v>v<>>>v^<^<# +#<^<<^v>v><^v.>>^.vv>>^v<.vv^v<^v^.^^.<.vv>>v>>^<^<<.>>><<<<>vv>^.vv><^^>^>^v^>v>.<>>^v^<>^^^^v^v>>v<<<^v^>>^v^vvv>v>.><<^^>^<><><<<^vv<<<^<>>^^v># +#<><<<>v><^>vv<^><><>^<<^^>^.^^><.vvv<^<>^v^v^v>><>^<^>>><.v<^^>>^vvv^^^v<.>vv^v>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..>v^v^^..><# +#<^v<><^^<.>><<>^^<><.<.>^.vv>^vv>>.<><>^^>>>v<^^v.><<>><>^^<^><<><>>>>^.# +#><^<>v<^><><<<><^>^<^>^^v<><<<<>>><>.^.>vv>v>^^<<>^>.<^># +#.v<<<.v<^>>^<>>v<>v.><>^^v>vv<<^.v<^^v>.v>^v>^..^<<.<..^>^.^.v^^><>>>^..^vv># +#<>^>>^^v^>>>.>v^v<^^<<^<>v>>.>><<<><^v.v<>v><>^v>>>^^v<^>vv^v>^v>^.<<# +#>vvvv.>vvvvv^.<<<><^^v<<>^^.<^>v<^v>.^><>>v.<^.<<.^^.>vv<<<<^.>^^v>>><<# +#<^>.<<^^^<<>.<>v^^^v<<^>>vv<^.<>>v.^v<^^.v<>^^v>>v.^>vv<<<<>vvv<<.^>v>v<^v^vv^<^.^>v.>^.>^^<# +#<><^<><.>>^^>>v><^<^^v>>^>>^>^<>^>v<^><.<>v^<^v^<<..<..v^>>>v>v<<>..<>>>vvv><<# +#<>>vv>v.^v>.^<><>.v..<<^v>v^v>^^><.>>><<^>v^^^^vv.<>v.vv>>^<^.>^<>.<^>^<<^v^^v>^>vv>^<>.# +#>^>>v>v<>^<.<.>><^^<.vvv<<<.vv^>^>^^vv<^>^>vvv^^^.v<<<^^<>v<<>># +####################################################################################################.# diff --git a/2022/day24/main.go b/2022/day24/main.go new file mode 100644 index 0000000..9d17785 --- /dev/null +++ b/2022/day24/main.go @@ -0,0 +1,121 @@ +package main + +import ( + "fmt" + "strings" + + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +func main() { + input := h.StdinToStringSlice() + part1(input) + part2(input) +} + +func part1(input []string) { + field, blizzards, start, target := parseInput(input) + fmt.Println("# Part 1") + fmt.Println(run(field, blizzards, start, target)) +} + +func part2(input []string) { + field, blizzards, start, target := parseInput(input) + fmt.Println("# Part 2") + fmt.Println(run(field, blizzards, start, target) + + run(field, blizzards, target, start) + + run(field, blizzards, start, target)) +} + +type Blizzard struct { + pos, dir, wrap h.Coordinate +} + +var ( + U = h.Coordinate{X: 0, Y: -1} + D = h.Coordinate{X: 0, Y: 1} + L = h.Coordinate{X: -1, Y: 0} + R = h.Coordinate{X: 1, Y: 0} +) + +var directions []h.Coordinate = []h.Coordinate{U, D, L, R} + +func parseInput(lines []string) (field [][]rune, blizzards []Blizzard, start, target h.Coordinate) { + start.X = strings.Index(lines[0], "E") + if start.X == -1 { + start.X = strings.Index(lines[0], ".") + } + target.Y = len(lines) - 1 + target.X = strings.Index(lines[target.Y], ".") + for _, line := range lines { + line = strings.TrimSpace(line) + field = append(field, []rune(line)) + } + for y, row := range field { + for x, c := range row { + switch c { + case '^': + blizzards = append(blizzards, Blizzard{ + h.Coordinate{X: x, Y: y}, U, h.Coordinate{X: x, Y: len(field) - 2}, + }) + case 'v': + blizzards = append(blizzards, Blizzard{ + h.Coordinate{X: x, Y: y}, D, h.Coordinate{X: x, Y: 1}, + }) + case '<': + blizzards = append(blizzards, Blizzard{ + h.Coordinate{X: x, Y: y}, L, h.Coordinate{X: len(field[0]) - 2, Y: y}, + }) + case '>': + blizzards = append(blizzards, Blizzard{ + h.Coordinate{X: x, Y: y}, R, h.Coordinate{X: 1, Y: y}, + }) + } + } + } + return +} + +func valid(field [][]rune, pos h.Coordinate) bool { + return pos.X >= 0 && pos.X < len(field[0]) && pos.Y >= 0 && pos.Y < len(field) +} + +func run(field [][]rune, blizzards []Blizzard, start, target h.Coordinate) int { + minutes := 0 + currentStep := make(map[h.Coordinate]bool) + currentStep[start] = true + + for !currentStep[target] { + //update blizzards + whereBlizzards := make(map[h.Coordinate]bool) + for i, b := range blizzards { + bb := b.pos.Add(b.dir) + if valid(field, bb) { + if field[bb.Y][bb.X] == '#' { + blizzards[i].pos = b.wrap + } else { + blizzards[i].pos = bb + } + } + whereBlizzards[blizzards[i].pos] = true + } + + //find new steps + newStep := make(map[h.Coordinate]bool) + for pos := range currentStep { + if !(whereBlizzards[pos]) { + newStep[pos] = true + } + for _, d := range directions { + n := pos.Add(d) + if valid(field, n) && field[n.Y][n.X] != '#' && !whereBlizzards[n] { + newStep[n] = true + } + } + } + currentStep = newStep + minutes++ + } + + return minutes +} diff --git a/2022/day24/problem b/2022/day24/problem new file mode 100644 index 0000000..4e27dc9 --- /dev/null +++ b/2022/day24/problem @@ -0,0 +1,366 @@ + Advent of Code + + • [About] + • [Events] + • [Shop] + • [Settings] + • [Log Out] + + br0xen (AoC++) 41* + +    int y=2022; + + • [Calendar] + • [AoC++] + • [Sponsors] + • [Leaderboard] + • [Stats] + + Our sponsors help make Advent of Code possible: + Smarty - Join our private leaderboard and solve our + puzzles for BIG PRIZES!!! ----------------- Address + Validation and Autocomplete, and more! + +--- Day 24: Blizzard Basin --- + + With everything replanted for next year (and with + elephants and monkeys to tend the grove), you and the + Elves leave for the extraction point. + + Partway up the mountain that shields the grove is a + flat, open area that serves as the extraction point. + It's a bit of a climb, but nothing the expedition can't + handle. + + At least, that would normally be true; now that the + mountain is covered in snow, things have become more + difficult than the Elves are used to. + + As the expedition reaches a valley that must be + traversed to reach the extraction site, you find that + strong, turbulent winds are pushing small blizzards of + snow and sharp ice around the valley. It's a good thing + everyone packed warm clothes! To make it across safely, + you'll need to find a way to avoid them. + + Fortunately, it's easy to see all of this from the + entrance to the valley, so you make a map of the valley + and the blizzards (your puzzle input). For example: + + #.##### + #.....# + #>....# + #.....# + #...v.# + #.....# + #####.# + + The walls of the valley are drawn as #; everything else + is ground. Clear ground - where there is currently no + blizzard - is drawn as .. Otherwise, blizzards are + drawn with an arrow indicating their direction of + motion: up (^), down (v), left (<), or right (>). + + The above map includes two blizzards, one moving right + (>) and one moving down (v). In one minute, each + blizzard moves one position in the direction it is + pointing: + + #.##### + #.....# + #.>...# + #.....# + #.....# + #...v.# + #####.# + + Due to conservation of blizzard energy, as a blizzard + reaches the wall of the valley, a new blizzard forms on + the opposite side of the valley moving in the same + direction. After another minute, the bottom + downward-moving blizzard has been replaced with a new + downward-moving blizzard at the top of the valley + instead: + + #.##### + #...v.# + #..>..# + #.....# + #.....# + #.....# + #####.# + + Because blizzards are made of tiny snowflakes, they + pass right through each other. After another minute, + both blizzards temporarily occupy the same position, + marked 2: + + #.##### + #.....# + #...2.# + #.....# + #.....# + #.....# + #####.# + + After another minute, the situation resolves itself, + giving each blizzard back its personal space: + + #.##### + #.....# + #....># + #...v.# + #.....# + #.....# + #####.# + + Finally, after yet another minute, the rightward-facing + blizzard on the right is replaced with a new one on the + left facing the same direction: + + #.##### + #.....# + #>....# + #.....# + #...v.# + #.....# + #####.# + + This process repeats at least as long as you are + observing it, but probably forever. + + Here is a more complex example: + + #.###### + #>>.<^<# + #.<..<<# + #>v.><># + #<^v^^># + ######.# + + Your expedition begins in the only non-wall position in + the top row and needs to reach the only non-wall + position in the bottom row. On each minute, you can + move up, down, left, or right, or you can wait in + place. You and the blizzards act simultaneously, and + you cannot share a position with a blizzard. + + In the above example, the fastest way to reach your + goal requires 18 steps. Drawing the position of the + expedition as E, one way to achieve this is: + + Initial state: + #E###### + #>>.<^<# + #.<..<<# + #>v.><># + #<^v^^># + ######.# + + Minute 1, move down: + #.###### + #E>3.<.# + #<..<<.# + #>2.22.# + #>v..^<# + ######.# + + Minute 2, move down: + #.###### + #.2>2..# + #E^22^<# + #.>2.^># + #.>..<.# + ######.# + + Minute 3, wait: + #.###### + #<^<22.# + #E2<.2.# + #><2>..# + #..><..# + ######.# + + Minute 4, move up: + #.###### + #E<..22# + #<<.<..# + #<2.>>.# + #.^22^.# + ######.# + + Minute 5, move right: + #.###### + #2Ev.<># + #<.<..<# + #.^>^22# + #.2..2.# + ######.# + + Minute 6, move right: + #.###### + #>2E<.<# + #.2v^2<# + #>..>2># + #<....># + ######.# + + Minute 7, move down: + #.###### + #.22^2.# + #>v<>.# + #>....<# + ######.# + + Minute 8, move left: + #.###### + #.<>2^.# + #.E<<.<# + #.22..># + #.2v^2.# + ######.# + + Minute 9, move up: + #.###### + #>.# + #.<<.<.# + #>2>2^.# + #.v><^.# + ######.# + + Minute 10, move right: + #.###### + #.2E.>2# + #<2v2^.# + #<>.>2.# + #..<>..# + ######.# + + Minute 11, wait: + #.###### + #2^E^2># + #2# + #.<..>.# + ######.# + + Minute 12, move down: + #.###### + #>>.<^<# + #.v.><># + #<^v^^># + ######.# + + Minute 13, move down: + #.###### + #.>3.<.# + #<..<<.# + #>2E22.# + #>v..^<# + ######.# + + Minute 14, move right: + #.###### + #.2>2..# + #.^22^<# + #.>2E^># + #.>..<.# + ######.# + + Minute 15, move right: + #.###### + #<^<22.# + #.2<.2.# + #><2>E.# + #..><..# + ######.# + + Minute 16, move right: + #.###### + #.<..22# + #<<.<..# + #<2.>>E# + #.^22^.# + ######.# + + Minute 17, move down: + #.###### + #2.v.<># + #<.<..<# + #.^>^22# + #.2..2E# + ######.# + + Minute 18, move down: + #.###### + #>2.<.<# + #.2v^2<# + #>..>2># + #<....># + ######E# + + What is the fewest number of minutes required to avoid + the blizzards and reach the goal? + + Your puzzle answer was 240. + +--- Part Two --- + + As the expedition reaches the far side of the valley, + one of the Elves looks especially dismayed: + + He forgot his snacks at the entrance to the valley! + + Since you're so good at dodging blizzards, the Elves + humbly request that you go back for his snacks. From + the same initial conditions, how quickly can you make + it from the start to the goal, then back to the start, + then back to the goal? + + In the above example, the first trip to the goal takes + 18 minutes, the trip back to the start takes 23 + minutes, and the trip back to the goal again takes 13 + minutes, for a total time of 54 minutes. + + What is the fewest number of minutes required to reach + the goal, go back to the start, then reach the goal + again? + + Your puzzle answer was 717. + + Both parts of this puzzle are complete! They provide + two gold stars: ** + + At this point, you should return to your Advent + calendar and try another puzzle. + + If you still want to see it, you can get your puzzle + input. + + You can also [Shareon Twitter Mastodon] this puzzle. + +References + + Visible links + . https://adventofcode.com/ + . https://adventofcode.com/2022/about + . https://adventofcode.com/2022/events + . https://teespring.com/stores/advent-of-code + . https://adventofcode.com/2022/settings + . https://adventofcode.com/2022/auth/logout + . Advent of Code Supporter + https://adventofcode.com/2022/support + . https://adventofcode.com/2022 + . https://adventofcode.com/2022 + . https://adventofcode.com/2022/support + . https://adventofcode.com/2022/sponsors + . https://adventofcode.com/2022/leaderboard + . https://adventofcode.com/2022/stats + . https://adventofcode.com/2022/sponsors + . https://www.smarty.com/advent-of-code + . https://adventofcode.com/2022 + . https://adventofcode.com/2022/day/24/input + . https://twitter.com/intent/tweet?text=I%27ve+completed+%22Blizzard+Basin%22+%2D+Day+24+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F24&related=ericwastl&hashtags=AdventOfCode + . javascript:void(0); diff --git a/2022/day24/testinput b/2022/day24/testinput new file mode 100644 index 0000000..158014b --- /dev/null +++ b/2022/day24/testinput @@ -0,0 +1,7 @@ +#.##### +#.....# +#>....# +#.....# +#...v.# +#.....# +#####.# diff --git a/2022/day24/testinput2 b/2022/day24/testinput2 new file mode 100644 index 0000000..685dc4f --- /dev/null +++ b/2022/day24/testinput2 @@ -0,0 +1,6 @@ +#.###### +#>>.<^<# +#.<..<<# +#>v.><># +#<^v^^># +######.# diff --git a/helpers/coordinate.go b/helpers/coordinate.go index 157487a..184a33d 100644 --- a/helpers/coordinate.go +++ b/helpers/coordinate.go @@ -38,6 +38,12 @@ func (c *Coordinate) MoveNW() { c.X-- c.Y-- } +func (c Coordinate) Add(o Coordinate) Coordinate { + return Coordinate{ + X: c.X + o.X, + Y: c.Y + o.Y, + } +} func (c Coordinate) North() Coordinate { return Coordinate{X: c.X, Y: c.Y - 1}