From c4d5dae4564b582f6bb53fa8ccdd50861212bbfe Mon Sep 17 00:00:00 2001 From: Brian Buller Date: Tue, 20 Dec 2022 15:04:26 -0600 Subject: [PATCH] 2022 Day 17 part 1 Complete --- 2022/day17/input | 1 + 2022/day17/main.go | 294 +++++++++++++++++++++ 2022/day17/problem | 404 +++++++++++++++++++++++++++++ 2022/day17/testinput | 1 + 2022/day19/input | 30 +++ 2022/day19/main.go | 176 +++++++++++++ 2022/day19/problem | 240 +++++++++++++++++ 2022/day19/testinput | 2 + helpers/coordinate.go | 37 +++ helpers/growUpCoordinateByteMap.go | 112 ++++++++ 10 files changed, 1297 insertions(+) create mode 100644 2022/day17/input create mode 100644 2022/day17/main.go create mode 100644 2022/day17/problem create mode 100644 2022/day17/testinput create mode 100644 2022/day19/input create mode 100644 2022/day19/main.go create mode 100644 2022/day19/problem create mode 100644 2022/day19/testinput create mode 100644 helpers/growUpCoordinateByteMap.go diff --git a/2022/day17/input b/2022/day17/input new file mode 100644 index 0000000..34b03bf --- /dev/null +++ b/2022/day17/input @@ -0,0 +1 @@ +>><<<>><<<<>>><>><>>><<<>>>><>>><<><<<>>>><<<><<<><<><<<>>>><<><<>>><<<<>><<>><<<><<<<>><<<<><>>><<<<>>><<<>>>><<<>>>><<<<>>><<>>><<>>>><<<<>>>><<<<>><>>>><<<<>>><<>><>>><>>><<<<>>><<>>><>><<<>>>><<>>>><<<>>><<<>>>><<<<><<<><<>>><>><<<<>><>><<><<<<>>><<>>><<<>>>><<<<>>><<>>>><<<<>><>><<<><<>><<<>>>><<<>><<<<>>>><<<><<<<>>><<><>>><<>><<<>>><<<<>>><<>>>><<<>>><<<<>>><<>>>><<<<>><<>>>><<<>>>><<>>><<><<<>>><<<<>>>><<<<>>><<<>>>><<<<>><<<>>>><>>><><<>>><<<><<>>>><<<>>>><<><<<<>>>><<<><<>><<<<>>>><<>>><>>>><<<<>><<>>><<>>><<>><>><><<<<>>>><<<>><<>>><<><<<<>>>><<<<><<<<>>>><><<>>><><>>><<>>><>>><>>>><<>><><<>><>>><<>>>><<>>>><<<<><<<>>>><>><>>>><<<<><<<><<<>>>><<><<>><<<>>><<<<>>><<<<><<>>><<<>>>><<><<<<>><<<<>><<<><>><>>>><><<<>>><<<<><<<<>><>>><<<>><<<<><<<>>>><<<>>>><<<>><<>><<<<>><<<<>><>>>><<>>>><<<<>>><<>>>><<>>>><>><<<>>>><<<<>>><<<<><>>>><<><<<>><<<<>>>><<<<>><>>>><<<>>>><<<<>>>><<<<>>><<<<>><>>><<<<><>>>><<><>>>><>><<>>>><>>>><<>><<>>><<<>>>><<><<<>>>><<><<>><<<<>>><<<>>><<<<>><<<><<<>>><<><<>>>><<<>>><<>>><<<><<<<>>><>>>><<<>>><<<>>>><<><><<>>>><<>>>><<>>>><<>>><<>><<><<<>>><>>><<<<>>>><>>>><<<>><>><<<<>>><<<<>>><<>>><<<<><<<>>><>>>><<>><<<<>><<<<>><<<<><>><<<<>>>><<>>><>><<<>><<>><<<<>><<>>><<<<>>><<<<>>><<><<<>>><<><<<><<>>>><>><<><<<<><<>><<<>>>><><<<<><><><>>><<<>>><<>>><<<>>>><<><<>><<>><<<><<<<>>>><>>>><<>>>><<<>>>><<>>>><<<>><>><<<>>><<>>>><<><<>>>><<<><<<<>>><<<>>>><<<>>><<<><>>><<>>><<<>>>><<<>>>><<<>>>><<<>><>><<<>>><<<<>>>><><<<>>>><<>>>><><>>><<>>>><<>><<>>>><<<>><<<>>>><<>>>><<<<>><<<>><<<>><<>><<<>>><<><>>><<><<><>>>><<<>>>><<<<>><<>>>><<<<>><><<<>>><<<<>><<>>><<<>><<>><<>><>>>><<><<>>>><>>>><<><><<<><<<<>>>><<<<>><<><<><<>>>><>>><<<><<<<><<>><<<><<>><><<><<<>>>><>>>><<>>>><>><><><<<><<><<>>><<<<><<>><<<>>>><<><<<<>>>><<<<>><><<<<>><<>><>><<<<>>>><<>>>><<<<><<<>><<>>><<<>>><>>><<>>>><<<><<<<><<>>>><<<<>><<<>>>><<<>><<<<><<<>><<<<>><<<>>>><<>>>><><>>><>>><<<>>>><<>>><<<>><>>>><<<>>>><<<<><<<>>><<<<>><<>><<>><<<><<<<>>><><>><<<><<<>>><<<><<<<>>>><><<<<>><<>><>>><<<>>>><<>>><<<>><<<<>>><<<>><<>><<>><<<<><<>>><>><<>>><<><<<><<<>><<<<>>><>><><<<<>>>><<<><<<>><>><<>>>><<<>>>><<<><<<>>><<>>><><>><<<>><>>>><<<<>>>><<<<>>><<<<>>><<<<>><<<<><><<>><>><<>>><<>><<><<<<>>>><<<<>>>><<>>>><<<<>>>><<>>>><>>>><<>><<><<<><><>><<<><<<<>>>><<<<>><<<>>>><<<<>>>><>>>><><<<<>><>>><<<<><<>>>><>><<<<>><<<><<<>>>><<>><<>>><>>>><<><>>>><<<<><<><<<>>>><<<>>>><<><>><<<>><<<>><<<<><<>>><>><<>>><<>>><>>>><<<>>><<>><<><><<>>>><<<>>><<<>><<<>>><<<>>>><<>>><>>>><>>>><>>><<>>>><<<>><<<<>><<<<>><<>>>><><>>>><<>>>><<<><<<<><<>>>><<<<>><<<<>>>><><<<><>><<<<>>>><>>>><<<<>>>><<><>><<<<><<<>>><<<<>><>><>>>><<>>>><>>><>>>><>><<>>><<<><>><>>>><<<>><<<>><<<<><<<<>>><<<>>><<<>>>><>><>>><<<<>><<<><<>>><>>><<><>>>><<<>>>><<<<>>>><><<<>>><<<<>>><>><>>>><<<>><<>>>><>>><<<<>>>><<<>><<<>>>><<<<>><<<>>><<<<><<<<>>>><><<<>>><<<<>>>><<<<>><<>><<<>>><>>><>><<>>><<<>><><<><>><<>><>><<<><<<<>>><<<>><<<><<<>>>><<>>><<<<><<><<<>>><<<<>>><<>><>>><>>><<<><<>>>><<<>><<<<><<<>><<<<>><>><<>><>>>><>>>><<>>><<<<>>><><><><<<>>><<<>><<>>><<<<>>>><>><<<>>>><<>><<<<>><<>><>><<<>>>><>>><<<<>>><>><<>>><<<>><<<<>>>><<<>><<>><>><<<<>><<<><<<>><>><<<><<<>>>><<<<>>><<><<<<><<<<>>>><<<><>><<><>>><<<><<><<<<>>><<>>>><>><<<<>><<<<>>><<>>>><>>><<<>>><<<>>>><<>>><>>>><<<<><>><<>>>><<<>>><>>><>><<<>>>><<><<<>>>><<><<<<>>>><<<<>>>><><<<<>>>><<<>>>><<><<<>>>><<>><>><>>><<<<><<<>>>><<<<>>>><<<><<>>>><<<><>>>><<<<>>>><>>><<<>><<<<><<>>><<>>><<>>><>>><<<><><><<<>>>><<>>>><<<<><>>>><<<>><<>>>><<><<<<><<<<>><><<<<><<>>>><<<>><<<<>><<>><<><<>>>><<><<<><<<<><<<<>>><<<>>>><<<<>>><><<<>>><>>>><>>><<<<>>><<<>>><<<<><<<<><<>><><<<>>><>>><<><<><<>><<<<>>>><<<>><<<><<<<>>><<<<>>><<>><<<<>><>>>><>><<<><>>>><<<>>><<><<>><<<><<<>><<<<>><<<<>><<<<><>>>><<><<<>><<<><<<>><<<<><<>>>><<<>><<<><<<>>><<<><<<<>>>><<>>>><<<>><<<<>>><<><<<<>>>><<<<>>>><<>><<><<>>><<>>>><<>>><<>>><<<>>>><<>>><<><<>>><<<>><<<<>>><<>>><<<>>><<<>>><>>>><<<>>>><<<<>>>><>>>><<<>>>><<<>>>><>>>><>>>><<<><<>><><>><<>><><<<>>>><><>>>><><<<><>>><<<>>><<<>>><<<<>><<<<><<<>>><<>><<<<>>><<<>><<>>>><<><<<<>>><>><<<>>>><<>><<<<>>><<<<>>><>>>><<><<<>><<<<>>>><<>>>><<<<><<>><<>>><>>><><<<<>><<><<<>>>><<<<>>>><<<>>><<>>><><><<<<>>>><<>><><<<<><<<<>>>><<>>>><><<<><>>><>>>><<<><<<<>><<<<>>>><<<><<>><>>>><<>>>><<>>><<<><<<><<<<><<<<>><<<<><<<>>><><<<>>><<<>>>><<><<<<>>><>><<><<><>>><<>>><<<<>>>><<>>>><><<<<>>>><<><<<>>><<<><<<<><<<<>><<<>><><<>><<<<><<<><><<<>>><>>>><<<<>>>><<>>><<>>>><<>>>><<<<>><<<>><<>>>><>><>><<>>><<<<><>>><<<>>><<<<>>>><<>><>>>><<><<<<><<>>>><<<>><>>>><<>><>><<<<><<<<>>><>>>><><<<<>><<<>>><><<><>>>><<>>><<<<>>><>>>><<<<>>>><><>><>><<<>><<>><<<><>>>><><<<<>>><<><<<>>>><<<>><<>>><<<>><<<>>>><<>>>><>><><<>>><<>><>>><<<><<<>>>><<<<><<>>><<<>>>><<<<><<<<>>>><>><<<>><<><>>>><><<>>>><<><<<<>><<>>><<><<<>>>><>><<<>><<>>><<>><>>><<<>>><<<<>>><<<<>>>><<<>>>><<<><<>><>><<>>><>>><<>>>><<>>><<<<>>><>>>><<<<>><<<<>>>><<<<><<<>>><>>><<<><<<<><<<>>>><>>><>>>><<>>>><<>>>><<<>>>><><<<>><<>>>><<<><<>><<>>><<>>><<<>><<<><<><<>>>><>>>><<<<><<>>>><<><<<<><>>><<>><<>>><<>>>><<<><>>><<>>><<>>><<>><<<>><<>><<<<>>>><<><<<>>>><<<<>>>><<<>>><><>>><<>>><<>><<<<>>><<><>>>><<<<>>><<>>><<<><>>><>>><<<>>><<<<><<<>>>><<<>>>><<<>><<<<>>>><<<<>>>><<>>><<<<>>>><>>>><<<>>><<<<>>>><<><<<>><<<>>><<<>>><<>>><<<<><>>><<<>>>><<>>>><<<>>>><>><<<<><<<<>><<>>>><<<<>>><>><<<>><<<<><<>>>><<<<>>><<<>>><>><<><<<>>>><<<<>>>><<<<>><<<<>>>><<<<>>><<>>><<<>>>><>>><<<<>><<<<>>>><>>>><<<<><<>>><<<><<>>>><>>><<<>>>><<>>>><<>>><<<<><<<<><<>>>><<>>>><><<<<><>><<<<>>>><<<>><<>><<>>>><<><<<><<<<><<<<>>><><<><<<<>><<>>>><<<<>>>><<<<>>>><<>>>><<<>>>><<>>><<<>>>><<<><<>><>>>><><>><>><<<<>>><<<<><<<>>>><<>>><<<>><><<>><<<<>>>><<<><<<>><<<<>>><<<<>><<>><<>>>><<>>>><>>>><>>><<><<>>>><<<>><><<>>>><<<>>><<>>><<<>>><>>><<<<>><<<<><<<>><<>>>><<<>>><>>><<<<>><<<<>>>><<<<>><<<<><<<<><>>>><><<>>>><>>><<<<>>><<<<>>><>>>><<<><<>>><>>>><><<<<><>>>><>><<<><<>>><<><<<<>>><<<<>>><<<>>><<<>>><<>>>><<>>>><<<>><<<><<>>>><<<<>>><>>><<<><<<><>>><<><<>>>><>>>><<<<>><><<>>>><>><<<>>><>><<<<>>>><<<>>>><<<><><<<>>>><<>><<<>>>><<<><<>>><<>>><>>>><<>><<<<>>>><<>><>><<<>>>><>><<<<><<>><>>>><<<<>>>><<><<<>>>><<>>><<<>>><<<>><>>><<<>>><<<><<<>><<<<>>><<<<>><<>>>><>>><<<<>>><<<<>>><>>>><<<<><<>><<<<><><<<<><<<<>><<<<>>><<>>><>><<><<>>>><><<<><<<<><<<>>><>>>><<<<>>><>>>><>>>><<<<>>><<><>>>><<<<>><<<>>><<>>><<<<>>>><>>>><>>><<>><<<>><<<<>>>><<<<>><>>>><<>>><<<><>>>><<<>>><<<><>>>><<<<>><>><<<>>>><>>>><>>><<><<>>>><<>>><<<<>><<<>>><<>>>><<<>>>><<>>>><<<>>><<>><>>><>>>><<>>>><<<<>><<<><>>><<<>>>><<>><<>><>><<>><>>>><>>><<<>>><>><>><<<><>><<<<>>><<<>>>><<<<><<<<><<><<><<<>>><<<><<>><<>><<<>>>><<>>><<>><<<<>><<>><<<<>><>>><<<>>><<>>>><<>>>><<<<><<>><<<<>><<<<><>><<<<><<<<><<<<>>><<<<>><<<<><<<>><>>><>>><<<<>>>><<<<>><<<<>><><<<>><>>><<><<><<<<>>><<>>>><<<<><<<<>><<>><>><<<>>>><<>>><<<<><>>>><<<<>>><<<>>>><<<>>><<<<>><<<<>>><<>>>><><<<<>>><<<<>><<>><<<><><<<><<<><<>>>><<><<<><<>><<<><<<<>>><<<>>><<<<><<>>><<<><<<>>>><><<>>>><<<<><<<<><<<>>><<>>><<<<>>>><<<><>>><<>><<>><<<<>>><<<<><>>><>>><<>>>><><<<<>><><<<<>>><<>><<<<>>>><<<<>><>>>><>><<<<>>>><<>>><<<>>>><<<>><><<>><<<>>><<<>>>><>>>><<<<>><<>><<<>>><<<>>>><<<>>><<<<><<>>>><<<<>><<><<>>>><<<><>>>><<<>>>><>>>><<>>>><<<><<<><<<<>><>>>><<<<>>><><<>><>>><>>><<<>>>><<><>><>><><<<><>><<>><<<<>>><<<>><<<><<>><<<>>>><<<>>><<<<>>><<<>>>><<<>>><<<<>><<<>><>><<<<>>><<<<><<>>><<<<>>><<<>>><>><<><>>><>>>><<<>><<>>><<>>>><<<>>>><>><<><>>>><<<<><<<<><>><<<<>>><<<>>><<<>>><<<<>><<<<>><<<>><>><<>><<<>><<>>><>><<<<>><>><>><<><>><<>>><<><>><>><>><<>>><<<><<><><<>>><<>>>><><<>>><>>>><<<>>><<>>><<<<>>>><>>><<>>>><<><<<>>>><<<<>><>>>><<<<>>>><<<>>>><>>>><<>>><>>>><><><<<><<<<>><>>><<<<><>>>><<<<>>><<<>><<<<><<<<><<<>>>><<>>>><<<><<<>><<>><<<><<>>><<<>>><><<<>>>><<>><<>><>>><<<<>>>><<<<>><>><<<<>>><<<<>>><><<<>>>><<<>>><<<<>><<<><<<<>><<<>>><<<<>><<<>>>><>>><<><<>>>><<<>><<<<>>>><<<>>>><<<<>><<>>>><>>><<<>><<<><<<<><<<>>>><<<<><<>>>><<<<>><<<<>>><>><<<>><<<<>>><>><<><<>>><<<>><<<<>>><><<<>>><<<>>>><<<<>><<>>>><>>><<<<>><<<><>><<<<>>>><<<>><<<><<<>>>><<<>>>><<<<><><>>><<<>><<<<>>>><<<>>>><>><<>><>><>><<<<>>>><<<<>><>><<<<>>>><<<>>><<>>>><<>>><<>><<>>>><<<>>><<>>>><<<>>>><>><<<<>>><<>>>><><<<>>><<<<><>>><>>><<>>>><<>>>><<<>>>><<>>><<<>>>><>>><<><<>>>><<<>><<>><<<><<<<><<<<>>>><<>><>>>><<>>>><>><<><><<><>>><>>>><<<>>><<<>>><<><<<>>>><<>>>><<<<><><>><<>>><<<<>><<<<>>>><>>><<<<>>><<<><<><<>><<>>><<<><<<<>>>><<>><<<>><<<<>>><<<>><<<<><<<>>>><>>><<>>>><<<>>>><<<><>>>><>>><>><<>>><<>>><<<<><>>>><<>>>><<<<><<><<<<>><<><<<>>>><<<<>><<><<<<>>><>><>>>><<<>>>><>><>>>><<<>>><<><<<<>>>><>>>><>>>><<<>><<>>><<<>>><<<><>><<><<<<><<<<>>>><<<<>><<<<><<<><<<<>>>><>>><<<>><<<<><>>><>><<>>><<>><<>><<<>>><><>><<<>>><><<>>><<<<>>><<<<><>><<<>><<<<>><<<<><<<>>><<<<>>>><><<>>><<<>><<><<>><<>>>><<<<><>>>><<>>><>><<<<>><<<<>>><<>>><<<>>><>><<<><<<>><<<>>>><><>>><<<<>>>><<><>>><<>>>><<<<>><<<<>><<<<><<>>><<>>>><<<><<>>><><<<>>><<<<>><><>>>><<<>>>><<>>>><<>>>><<<<>>><<<<>>>><<<><<<<>>><>>><><>><>>><<>>>><>>><<>>>><>>>><><>>><>>><<<<>><<<<>>><<<<><<<<>>><><>>>><<>><<<<>>><<<>>>><<<>><<<>>><<<>>><<<<><><<<<>>>><<<>>>><<><<<>>><<<>>><>><<><>><<<<>>><>>><<<>><><<<>><<<<>>><>><<<<>>><<>><<<>><<<>>>><<<>><<<>>><<>><>><>>><>>>><<<>>><<<<><<<>>>><<<<>><<<>><<<<>>>><<><<<>><<>>>><<<<><<>>><<<<>><>>>><>>>><<<>>>><>>><<<<>><<>>>><>>>><<<>>><<>>><<<<><<<<>><<><<<>>>><<<<>><<>>><>><><<>>><<<<>><<<<>>>><>>>><<>><<><<<<><<<<>><>><<<>><>><><<<<>>>><<<<><<<<><<<>>><>>><>>><<>><<>>>><<>>><<<>><<<<>>><>><>>><>>><>>><<<<>><><<<<>><<>>><<>>><<<<>>>><<<<>>>><>>><>>><>>>><<<>>>><<<>>><>>><<>>>><<<<><<<<>>><<<>>>><<<>>>><>>><<<<>><<<>><>>>><<>>>><<<<>>><<<<>>>><<<>>>><<<>><<>><<<>><<<>><<<<>>><<<<>>><<<<><<<>><<><><<<<>><<<<><<<>>><<<<>>>><>>>><>>><<>><><<<<>><<<<>><><>>>><<<<>>><<>><<>>>><>>><<<><<>>>><<<<>><<<>>>><<<>>><<<<>>><<>>><<<<><<<<>>><<>><<>>><>>>><<<><<><>>><>>>><<<<>>>><<<<>>><<<><><<<>>>><><<<<>>>><<<<>>>><<><<<<>>><><<>>>><<<>>>><<><<>>><<>>><<>>><<<<>>>><<<<><<<<>>>><>>>><>><<>><><<<><<>>>><<>>>><><<<<>><<>>>><<><<<><>>>><<<<>><<<>>>><<<>><>>><<<<>>><<<<>>><>><<>><><<<<>><<>><<<<>><>>>><>>><<<><<<<>><<<<><>><<<>><<<<> diff --git a/2022/day17/main.go b/2022/day17/main.go new file mode 100644 index 0000000..e12944f --- /dev/null +++ b/2022/day17/main.go @@ -0,0 +1,294 @@ +package main + +import ( + "fmt" + "os" + "time" + + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +const ( + dirU = iota + dirR + dirD + dirL + + rocks = 5 + + debug = false +) + +var ( + emptyRow = []byte{'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'} + bottomRow = []byte{'+', '-', '-', '-', '-', '-', '-', '-', '+'} +) + +func main() { + inp := h.StdinToString() + //fmt.Println("# Part 1") + //simulate(inp, 2022) + fmt.Println("# Part 2") + simulate(inp, 1000000000000) +} + +func stateAndSleep(m *h.GrowUpCoordByteMap) { + if !debug { + return + } + fmt.Print(h.CLEAR_SCREEN) + //fmt.Println() + fmt.Println(m) + time.Sleep(time.Second / 10) +} + +var cache map[string][]int + +func simulate(jets string, numRocks int) { + cache = make(map[string][]int) + m := h.NewGrowUpCoordByteMap() + m.PutBytes([][]byte{ + bottomRow, emptyRow, emptyRow, emptyRow, emptyRow, + emptyRow, emptyRow, emptyRow, + }, h.Coordinate{X: 0, Y: 0}) + m.StringEmptyIsSpace = true + + jetIdx := 0 + rockType := 0 + var state string + var height int + var turboHeight int + var cacheDisabled bool + for rockNum := 1; rockNum <= numRocks; rockNum++ { + fmt.Println(h.CLEAR_SCREEN) + fmt.Println("Simulating:", rockNum, "/", numRocks) + h.PrintProgress(rockNum, numRocks) + fmt.Println("\nHeight:", height) + if !cacheDisabled { + state, height = GetState(rockType, jetIdx, m) + if v, ok := cache[state]; !cacheDisabled && ok { + // Ok, we've got a duplicate. Go full turbo. + //addHeight := height + mult := numRocks / rockNum + newRockNum := rockNum * mult + turboHeight = height * mult + /* + for rockNum+v[1] <= numRocks { + rockNum = rockNum + v[1] + height = height + addHeight + fmt.Println(h.CLEAR_SCREEN) + fmt.Println("Simulating:", rockNum, "/", numRocks) + h.PrintProgress(rockNum, numRocks) + fmt.Println("\nHeight:", height) + } + */ + fmt.Println(h.CLEAR_SCREEN) + fmt.Println("Simulating:", rockNum, "/", numRocks) + h.PrintProgress(rockNum, numRocks) + fmt.Println("\nHeight:", height) + fmt.Println("State", state, "\nV:", v, "\nMult:", mult, "\nRockNum:", rockNum, "\nNewRockNum:", newRockNum, "\nTurboHeight:", turboHeight) + cacheDisabled = true + os.Exit(0) + } else { + cache[state] = []int{rockNum, height} + } + } else { + fmt.Println("\nHeight:", turboHeight+GetHeight(m)) + } + AddFallingRock(rockType, m) + stateAndSleep(m) + doJet := true + for { + if !doJet && AtRest(m) { + break + } + shiftDir := dirD + if doJet { + switch jets[jetIdx] { + case '>': + shiftDir = dirR + case '<': + shiftDir = dirL + } + jetIdx = (jetIdx + 1) % len(jets) + } + ShiftRock(shiftDir, m) + stateAndSleep(m) + doJet = !doJet + } + // The falling rock has stopped + StopRock(m) + stateAndSleep(m) + rockType = (rockType + 1) % rocks + } + fmt.Println("After", numRocks, "the tower is", GetHeight(m), "blocks tall") +} + +func GetState(r, j int, m *h.GrowUpCoordByteMap) (string, int) { + ret := fmt.Sprintf("%d;%d;", r, j) + for x := 1; x < 7; x++ { + for y := m.TLY; y > 1; y-- { + if m.Get(h.Coordinate{X: x, Y: y}) == '#' { + ret = fmt.Sprintf("%s-%d", ret, m.TLY-y) + break + } + } + } + return ret, GetHeight(m) +} + +func GetHeight(m *h.GrowUpCoordByteMap) int { + return h.GetHighestY(m.FindAll('#')...) +} + +func FindTopAtRestY(m *h.GrowUpCoordByteMap) int { + rockSpots := m.FindAll('#') + if len(rockSpots) != 0 { + return h.GetHighestY(rockSpots...) + } + return 0 +} + +func StopRock(m *h.GrowUpCoordByteMap) { + rockSpots := m.FindAll('@') + for i := range rockSpots { + m.Put(rockSpots[i], '#') + } +} +func ShiftRock(dir int, m *h.GrowUpCoordByteMap) { + if !CanShift(dir, m) { + return + } + + rockSpots := m.FindAll('@') + for i := range rockSpots { + m.Put(rockSpots[i], ' ') + } + for i := range rockSpots { + switch dir { + case dirU: + m.Put(GetUp(rockSpots[i]), '@') + case dirR: + m.Put(GetRight(rockSpots[i]), '@') + case dirD: + m.Put(GetDown(rockSpots[i]), '@') + case dirL: + m.Put(GetLeft(rockSpots[i]), '@') + } + } +} +func CanShift(dir int, m *h.GrowUpCoordByteMap) bool { + rockSpots := m.FindAll('@') + switch dir { + case dirU: // Shouldn't need to, though. + return true + case dirR: + for i := range rockSpots { + tst := m.Get(GetRight(rockSpots[i])) + if tst != '@' && tst != ' ' { + return false + } + } + return true + case dirD: + for i := range rockSpots { + tst := m.Get(GetDown(rockSpots[i])) + if tst != '@' && tst != ' ' { + return false + } + } + return true + case dirL: + for i := range rockSpots { + tst := m.Get(GetLeft(rockSpots[i])) + if tst != '@' && tst != ' ' { + return false + } + } + return true + } + return false +} +func AddFallingRock(tp int, m *h.GrowUpCoordByteMap) { + rock := GetRockBytes(tp) + pos := h.Coordinate{X: 3, Y: FindTopAtRestY(m) + 4} + for pos.Y+3 > m.TLY { + m.PutBytes([][]byte{emptyRow}, h.Coordinate{X: 0, Y: m.TLY + 1}) + } + m.PutBytes(rock, pos) +} +func AtRest(m *h.GrowUpCoordByteMap) bool { + rockSpots := m.FindAll('@') + if len(rockSpots) == 0 { + return true + } + for i := range rockSpots { + pos := GetDown(rockSpots[i]) + wrk := m.Get(pos) + if pos.Y == m.BRY { + return true + } + if wrk != ' ' && wrk != '@' { + return true + } + } + return false +} + +func GetRockBytes(tp int) [][]byte { + switch tp { + case 0: + return [][]byte{{'@', '@', '@', '@'}} + case 1: + return [][]byte{ + {' ', '@', ' '}, + {'@', '@', '@'}, + {' ', '@', ' '}, + } + case 2: + return [][]byte{ + {'@', '@', '@'}, + {' ', ' ', '@'}, + {' ', ' ', '@'}, + } + case 3: + return [][]byte{ + {'@'}, + {'@'}, + {'@'}, + {'@'}, + } + case 4: + return [][]byte{ + {'@', '@'}, + {'@', '@'}, + } + } + return [][]byte{} +} + +func GetLeft(c h.Coordinate) h.Coordinate { + return h.Coordinate{X: c.X - 1, Y: c.Y} +} +func GetRight(c h.Coordinate) h.Coordinate { + return h.Coordinate{X: c.X + 1, Y: c.Y} +} +func GetUp(c h.Coordinate) h.Coordinate { + return h.Coordinate{X: c.X, Y: c.Y + 1} +} +func GetDown(c h.Coordinate) h.Coordinate { + return h.Coordinate{X: c.X, Y: c.Y - 1} +} +func DirToString(shiftDir int) string { + switch shiftDir { + case dirU: + return "^" + case dirR: + return ">" + case dirD: + return "v" + case dirL: + return "<" + } + return " " +} diff --git a/2022/day17/problem b/2022/day17/problem new file mode 100644 index 0000000..21d96dd --- /dev/null +++ b/2022/day17/problem @@ -0,0 +1,404 @@ + Advent of Code + + • [About] + • [Events] + • [Shop] + • [Settings] + • [Log Out] + + br0xen (AoC++) 32* + +    sub 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 17: Pyroclastic Flow --- + + Your handheld device has located an alternative exit from the cave for you and the elephants. The ground is + rumbling almost continuously now, but the strange valves bought you some time. It's definitely getting warmer in + here, though. + + The tunnels eventually open into a very tall, narrow chamber. Large, oddly-shaped rocks are falling into the + chamber from above, presumably due to all the rumbling. If you can't work out where the rocks will fall next, you + might be crushed! + + The five types of rocks have the following peculiar shapes, where # is rock and . is empty space: + + #### + + .#. + ### + .#. + + ..# + ..# + ### + + # + # + # + # + + ## + ## + + The rocks fall in the order shown above: first the - shape, then the + shape, and so on. Once the end of the list + is reached, the same order repeats: the - shape falls first, sixth, 11th, 16th, etc. + + The rocks don't spin, but they do get pushed around by jets of hot gas coming out of the walls themselves. A quick + scan reveals the effect the jets of hot gas will have on the rocks as they fall (your puzzle input). + + For example, suppose this was the jet pattern in your cave: + + >>><<><>><<<>><>>><<<>>><<<><<<>><>><<>> + + In jet patterns, < means a push to the left, while > means a push to the right. The pattern above means that the + jets will push a falling rock right, then right, then right, then left, then left, then right, and so on. If the + end of the list is reached, it repeats. + + The tall, vertical chamber is exactly seven units wide. Each rock appears so that its left edge is two units away + from the left wall and its bottom edge is three units above the highest rock in the room (or the floor, if there + isn't one). + + After a rock appears, it alternates between being pushed by a jet of hot gas one unit (in the direction indicated + by the next symbol in the jet pattern) and then falling one unit down. If any movement would cause any part of the + rock to move into the walls, floor, or a stopped rock, the movement instead does not occur. If a downward movement + would have caused a falling rock to move into the floor or an already-fallen rock, the falling rock stops where it + is (having landed on something) and a new rock immediately begins falling. + + Drawing falling rocks with @ and stopped rocks with #, the jet pattern in the example above manifests as follows: + + The first rock begins falling: + |..@@@@.| + |.......| + |.......| + |.......| + +-------+ + + Jet of gas pushes rock right: + |...@@@@| + |.......| + |.......| + |.......| + +-------+ + + Rock falls 1 unit: + |...@@@@| + |.......| + |.......| + +-------+ + + Jet of gas pushes rock right, but nothing happens: + |...@@@@| + |.......| + |.......| + +-------+ + + Rock falls 1 unit: + |...@@@@| + |.......| + +-------+ + + Jet of gas pushes rock right, but nothing happens: + |...@@@@| + |.......| + +-------+ + + Rock falls 1 unit: + |...@@@@| + +-------+ + + Jet of gas pushes rock left: + |..@@@@.| + +-------+ + + Rock falls 1 unit, causing it to come to rest: + |..####.| + +-------+ + + A new rock begins falling: + |...@...| + |..@@@..| + |...@...| + |.......| + |.......| + |.......| + |..####.| + +-------+ + + Jet of gas pushes rock left: + |..@....| + |.@@@...| + |..@....| + |.......| + |.......| + |.......| + |..####.| + +-------+ + + Rock falls 1 unit: + |..@....| + |.@@@...| + |..@....| + |.......| + |.......| + |..####.| + +-------+ + + Jet of gas pushes rock right: + |...@...| + |..@@@..| + |...@...| + |.......| + |.......| + |..####.| + +-------+ + + Rock falls 1 unit: + |...@...| + |..@@@..| + |...@...| + |.......| + |..####.| + +-------+ + + Jet of gas pushes rock left: + |..@....| + |.@@@...| + |..@....| + |.......| + |..####.| + +-------+ + + Rock falls 1 unit: + |..@....| + |.@@@...| + |..@....| + |..####.| + +-------+ + + Jet of gas pushes rock right: + |...@...| + |..@@@..| + |...@...| + |..####.| + +-------+ + + Rock falls 1 unit, causing it to come to rest: + |...#...| + |..###..| + |...#...| + |..####.| + +-------+ + + A new rock begins falling: + |....@..| + |....@..| + |..@@@..| + |.......| + |.......| + |.......| + |...#...| + |..###..| + |...#...| + |..####.| + +-------+ + + The moment each of the next few rocks begins falling, you would see this: + + |..@....| + |..@....| + |..@....| + |..@....| + |.......| + |.......| + |.......| + |..#....| + |..#....| + |####...| + |..###..| + |...#...| + |..####.| + +-------+ + + |..@@...| + |..@@...| + |.......| + |.......| + |.......| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |..@@@@.| + |.......| + |.......| + |.......| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |...@...| + |..@@@..| + |...@...| + |.......| + |.......| + |.......| + |.####..| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |....@..| + |....@..| + |..@@@..| + |.......| + |.......| + |.......| + |..#....| + |.###...| + |..#....| + |.####..| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |..@....| + |..@....| + |..@....| + |..@....| + |.......| + |.......| + |.......| + |.....#.| + |.....#.| + |..####.| + |.###...| + |..#....| + |.####..| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |..@@...| + |..@@...| + |.......| + |.......| + |.......| + |....#..| + |....#..| + |....##.| + |....##.| + |..####.| + |.###...| + |..#....| + |.####..| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + |..@@@@.| + |.......| + |.......| + |.......| + |....#..| + |....#..| + |....##.| + |##..##.| + |######.| + |.###...| + |..#....| + |.####..| + |....##.| + |....##.| + |....#..| + |..#.#..| + |..#.#..| + |#####..| + |..###..| + |...#...| + |..####.| + +-------+ + + To prove to the elephants your simulation is accurate, they want to know how tall the tower will get after 2022 + rocks have stopped (but before the 2023rd rock begins falling). In this example, the tower of rocks will be 3068 + units tall. + + How many units tall will the tower of rocks be after 2022 rocks have stopped falling? + + To begin, get your puzzle input. + + Answer: _____________________ [ [Submit] ] + + 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/day/17/input + . https://twitter.com/intent/tweet?text=%22Pyroclastic+Flow%22+%2D+Day+17+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F17&related=ericwastl&hashtags=AdventOfCode + . javascript:void(0); diff --git a/2022/day17/testinput b/2022/day17/testinput new file mode 100644 index 0000000..97a1aa1 --- /dev/null +++ b/2022/day17/testinput @@ -0,0 +1 @@ +>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>> diff --git a/2022/day19/input b/2022/day19/input new file mode 100644 index 0000000..2fe476e --- /dev/null +++ b/2022/day19/input @@ -0,0 +1,30 @@ +Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 3 ore and 8 obsidian. +Blueprint 2: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian. +Blueprint 3: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 4: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 4 ore and 17 obsidian. +Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 8 obsidian. +Blueprint 6: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 2 ore and 20 obsidian. +Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian. +Blueprint 8: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 3 ore and 12 obsidian. +Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 4 ore and 12 obsidian. +Blueprint 10: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian. +Blueprint 11: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 14 obsidian. +Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 9 obsidian. +Blueprint 13: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 3 ore and 15 obsidian. +Blueprint 14: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 15: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 4 ore and 20 obsidian. +Blueprint 16: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 9 obsidian. +Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 2 ore and 15 obsidian. +Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 19: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 2 ore and 10 obsidian. +Blueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 18 obsidian. +Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 2 ore and 12 obsidian. +Blueprint 22: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 2 ore and 16 obsidian. +Blueprint 23: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian. +Blueprint 24: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 9 obsidian. +Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 5 clay. Each geode robot costs 3 ore and 18 obsidian. +Blueprint 26: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 2 ore and 10 obsidian. +Blueprint 27: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 4 ore and 14 obsidian. +Blueprint 28: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 15 obsidian. +Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 12 obsidian. +Blueprint 30: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 4 ore and 10 obsidian. diff --git a/2022/day19/main.go b/2022/day19/main.go new file mode 100644 index 0000000..0283bc3 --- /dev/null +++ b/2022/day19/main.go @@ -0,0 +1,176 @@ +package main + +import ( + "fmt" + "strings" + "time" + + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +func main() { + fmt.Println() + inp := h.StdinToStringSlice() + part1(inp) +} + +func part1(inp []string) { + blueprints := ParseBlueprints(inp) + robots := []Robot{{tp: ResOre}} + var ticks int + resources := make(map[Resource]int) + var done bool + printState(robots, resources) + useBP := blueprints[0] + _ = useBP + // TODO: Get Ratios of needed resources + for !done { + // First check if we can build some bots + if useBP.CanBuild(ResGeode, resources) { + resources = useBP.Build(resGeode, resources) + } + if useBP.CanBuild(ResObsidian, resources) { + resources = useBP.Build(resObsidian, resources) + } + if useBP.CanBuild(ResClay, resources) { + resources = useBP.Build(resClay, resources) + } + + // Every tick, each robot gathers one of it's resource + for i := range robots { + resources[robots[i].tp]++ + } + ticks++ + fmt.Println(h.CLEAR_SCREEN) + printState(robots, resources) + time.Sleep(time.Second / 10) + } +} + +func printState(robots []Robot, resources map[Resource]int) { + var oreBots, clayBots, obsBots, geodeBots int + for i := range robots { + switch robots[i].tp { + case ResOre: + oreBots++ + case ResClay: + clayBots++ + case ResObsidian: + obsBots++ + case ResGeode: + geodeBots++ + } + } + fmt.Printf( + "Bots: %2d Ore, %2d Clay, %2d Obsidian, %2d Geode\n", + oreBots, clayBots, obsBots, geodeBots) + fmt.Printf("[ Ore : %2d ]\n", resources[ResOre]) + fmt.Printf("[ Clay : %2d ]\n", resources[ResClay]) + fmt.Printf("[ Obsidian: %2d ]\n", resources[ResObsidian]) + fmt.Printf("[ Geode : %2d ]\n", resources[ResGeode]) +} + +type Resource int + +const ( + ResOre = iota + ResClay + ResObsidian + ResGeode + ResError +) + +type Robot struct { + tp Resource +} + +type Cost struct { + res Resource + count int +} + +type Blueprint struct { + costs map[Resource][]Cost +} + +func (b Blueprint) CanBuild(tp Resource, resources map[Resource]int) bool { + cost := b.costs[tp] + for _, c := range cost { + if resources[c.res] < c.count { + return false + } + } + return true +} + +func (b Blueprint) String() string { + ret := fmt.Sprintf("Blueprint contains %d Recipes.\n", len(b.costs)) + + for _, tp := range []Resource{ResOre, ResClay, ResObsidian, ResGeode} { + if v, ok := b.costs[tp]; ok { + ret = ret + fmt.Sprintf("Each %s robot costs %d %s", tp.String(), v[0].count, v[0].res.String()) + if len(v) > 1 { + ret = ret + fmt.Sprintf(" and %d %s", v[1].count, v[1].res.String()) + } + ret = ret + ". " + } + } + return ret +} + +func ParseBlueprints(inp []string) []Blueprint { + var ret []Blueprint + for i := range inp { + costs := make(map[Resource][]Cost) + wrk := strings.Split(inp[i], ": ")[1] + botReqs := strings.Split(wrk, ".") + for j := range botReqs { + if len(botReqs[j]) > 0 { + fields := strings.Fields(botReqs[j]) + bot := ResourceFromString(fields[1]) + var req []Cost + req = append(req, Cost{ + res: ResourceFromString(fields[5]), + count: h.Atoi(fields[4]), + }) + if len(fields) > 6 { + req = append(req, Cost{ + res: ResourceFromString(fields[8]), + count: h.Atoi(fields[7]), + }) + } + costs[bot] = req + } + } + ret = append(ret, Blueprint{costs: costs}) + } + return ret +} + +func ResourceFromString(s string) Resource { + switch s { + case "ore": + return ResOre + case "clay": + return ResClay + case "obsidian": + return ResObsidian + case "geode": + return ResGeode + } + return ResError +} + +func (r Resource) String() string { + switch r { + case ResOre: + return "ore" + case ResClay: + return "clay" + case ResObsidian: + return "obsidian" + case ResGeode: + return "geode" + } + return "unknown" +} diff --git a/2022/day19/problem b/2022/day19/problem new file mode 100644 index 0000000..8fc4015 --- /dev/null +++ b/2022/day19/problem @@ -0,0 +1,240 @@ + Advent of Code + + • [About] + • [Events] + • [Shop] + • [Settings] + • [Log Out] + + br0xen (AoC++) 29* + +    0xffff&2022 + + • [Calendar] + • [AoC++] + • [Sponsors] + • [Leaderboard] + • [Stats] + + Our sponsors help make Advent of Code possible: + Kotlin by JetBrains - Trees, lists, packages - itʼs Advent of Code time! Get ready to solve puzzles in Kotlin. + Watch us livestream our discussions about the solutions for the first few puzzles, join our leaderboard, win + prizes. Happy holidays! + +--- Day 19: Not Enough Minerals --- + + Your scans show that the lava did indeed form obsidian! + + The wind has changed direction enough to stop sending lava droplets toward you, so you and the elephants exit + the cave. As you do, you notice a collection of geodes around the pond. Perhaps you could use the obsidian to + create some geode-cracking robots and break them open? + + To collect the obsidian from the bottom of the pond, you'll need waterproof obsidian-collecting robots. + Fortunately, there is an abundant amount of clay nearby that you can use to make them waterproof. + + In order to harvest the clay, you'll need special-purpose clay-collecting robots. To make any type of robot, + you'll need ore, which is also plentiful but in the opposite direction from the clay. + + Collecting ore requires ore-collecting robots with big drills. Fortunately, you have exactly one ore-collecting + robot in your pack that you can use to kickstart the whole operation. + + Each robot can collect 1 of its resource type per minute. It also takes one minute for the robot factory (also + conveniently from your pack) to construct any type of robot, although it consumes the necessary resources + available when construction begins. + + The robot factory has many blueprints (your puzzle input) you can choose from, but once you've configured it + with a blueprint, you can't change it. You'll need to work out which blueprint is best. + + For example: + + Blueprint 1: + Each ore robot costs 4 ore. + Each clay robot costs 2 ore. + Each obsidian robot costs 3 ore and 14 clay. + Each geode robot costs 2 ore and 7 obsidian. + + Blueprint 2: + Each ore robot costs 2 ore. + Each clay robot costs 3 ore. + Each obsidian robot costs 3 ore and 8 clay. + Each geode robot costs 3 ore and 12 obsidian. + + (Blueprints have been line-wrapped here for legibility. The robot factory's actual assortment of blueprints are + provided one blueprint per line.) + + The elephants are starting to look hungry, so you shouldn't take too long; you need to figure out which + blueprint would maximize the number of opened geodes after 24 minutes by figuring out which robots to build and + when to build them. + + Using blueprint 1 in the example above, the largest number of geodes you could open in 24 minutes is 9. One way + to achieve that is: + + == Minute 1 == + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + + == Minute 2 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + + == Minute 3 == + Spend 2 ore to start building a clay-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + The new clay-collecting robot is ready; you now have 1 of them. + + == Minute 4 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 1 clay-collecting robot collects 1 clay; you now have 1 clay. + + == Minute 5 == + Spend 2 ore to start building a clay-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + 1 clay-collecting robot collects 1 clay; you now have 2 clay. + The new clay-collecting robot is ready; you now have 2 of them. + + == Minute 6 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 2 clay-collecting robots collect 2 clay; you now have 4 clay. + + == Minute 7 == + Spend 2 ore to start building a clay-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + 2 clay-collecting robots collect 2 clay; you now have 6 clay. + The new clay-collecting robot is ready; you now have 3 of them. + + == Minute 8 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 3 clay-collecting robots collect 3 clay; you now have 9 clay. + + == Minute 9 == + 1 ore-collecting robot collects 1 ore; you now have 3 ore. + 3 clay-collecting robots collect 3 clay; you now have 12 clay. + + == Minute 10 == + 1 ore-collecting robot collects 1 ore; you now have 4 ore. + 3 clay-collecting robots collect 3 clay; you now have 15 clay. + + == Minute 11 == + Spend 3 ore and 14 clay to start building an obsidian-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 3 clay-collecting robots collect 3 clay; you now have 4 clay. + The new obsidian-collecting robot is ready; you now have 1 of them. + + == Minute 12 == + Spend 2 ore to start building a clay-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + 3 clay-collecting robots collect 3 clay; you now have 7 clay. + 1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian. + The new clay-collecting robot is ready; you now have 4 of them. + + == Minute 13 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 4 clay-collecting robots collect 4 clay; you now have 11 clay. + 1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian. + + == Minute 14 == + 1 ore-collecting robot collects 1 ore; you now have 3 ore. + 4 clay-collecting robots collect 4 clay; you now have 15 clay. + 1 obsidian-collecting robot collects 1 obsidian; you now have 3 obsidian. + + == Minute 15 == + Spend 3 ore and 14 clay to start building an obsidian-collecting robot. + 1 ore-collecting robot collects 1 ore; you now have 1 ore. + 4 clay-collecting robots collect 4 clay; you now have 5 clay. + 1 obsidian-collecting robot collects 1 obsidian; you now have 4 obsidian. + The new obsidian-collecting robot is ready; you now have 2 of them. + + == Minute 16 == + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 4 clay-collecting robots collect 4 clay; you now have 9 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian. + + == Minute 17 == + 1 ore-collecting robot collects 1 ore; you now have 3 ore. + 4 clay-collecting robots collect 4 clay; you now have 13 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian. + + == Minute 18 == + Spend 2 ore and 7 obsidian to start building a geode-cracking robot. + 1 ore-collecting robot collects 1 ore; you now have 2 ore. + 4 clay-collecting robots collect 4 clay; you now have 17 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 3 obsidian. + The new geode-cracking robot is ready; you now have 1 of them. + + == Minute 19 == + 1 ore-collecting robot collects 1 ore; you now have 3 ore. + 4 clay-collecting robots collect 4 clay; you now have 21 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 5 obsidian. + 1 geode-cracking robot cracks 1 geode; you now have 1 open geode. + + == Minute 20 == + 1 ore-collecting robot collects 1 ore; you now have 4 ore. + 4 clay-collecting robots collect 4 clay; you now have 25 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 7 obsidian. + 1 geode-cracking robot cracks 1 geode; you now have 2 open geodes. + + == Minute 21 == + Spend 2 ore and 7 obsidian to start building a geode-cracking robot. + 1 ore-collecting robot collects 1 ore; you now have 3 ore. + 4 clay-collecting robots collect 4 clay; you now have 29 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 2 obsidian. + 1 geode-cracking robot cracks 1 geode; you now have 3 open geodes. + The new geode-cracking robot is ready; you now have 2 of them. + + == Minute 22 == + 1 ore-collecting robot collects 1 ore; you now have 4 ore. + 4 clay-collecting robots collect 4 clay; you now have 33 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian. + 2 geode-cracking robots crack 2 geodes; you now have 5 open geodes. + + == Minute 23 == + 1 ore-collecting robot collects 1 ore; you now have 5 ore. + 4 clay-collecting robots collect 4 clay; you now have 37 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian. + 2 geode-cracking robots crack 2 geodes; you now have 7 open geodes. + + == Minute 24 == + 1 ore-collecting robot collects 1 ore; you now have 6 ore. + 4 clay-collecting robots collect 4 clay; you now have 41 clay. + 2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian. + 2 geode-cracking robots crack 2 geodes; you now have 9 open geodes. + + However, by using blueprint 2 in the example above, you could do even better: the largest number of geodes you + could open in 24 minutes is 12. + + Determine the quality level of each blueprint by multiplying that blueprint's ID number with the largest number + of geodes that can be opened in 24 minutes using that blueprint. In this example, the first blueprint has ID 1 + and can open 9 geodes, so its quality level is 9. The second blueprint has ID 2 and can open 12 geodes, so its + quality level is 24. Finally, if you add up the quality levels of all of the blueprints in the list, you get + 33. + + Determine the quality level of each blueprint using the largest number of geodes it could produce in 24 + minutes. What do you get if you add up the quality level of all of the blueprints in your list? + + To begin, get your puzzle input. + + Answer: _____________________ [ [Submit] ] + + 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://kotlinlang.org/ + . https://en.wikipedia.org/wiki/Geode + . https://adventofcode.com/2022/day/19/input + . https://twitter.com/intent/tweet?text=%22Not+Enough+Minerals%22+%2D+Day+19+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F19&related=ericwastl&hashtags=AdventOfCode + . javascript:void(0); diff --git a/2022/day19/testinput b/2022/day19/testinput new file mode 100644 index 0000000..f39c094 --- /dev/null +++ b/2022/day19/testinput @@ -0,0 +1,2 @@ +Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian. +Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian. diff --git a/helpers/coordinate.go b/helpers/coordinate.go index abb8459..a5c7a39 100644 --- a/helpers/coordinate.go +++ b/helpers/coordinate.go @@ -134,3 +134,40 @@ func (c Coordinate) Adjacent(c2 Coordinate) bool { c2.Equals(c.West()) || c2.Equals(c.NW()) } + +func GetHighestY(list ...Coordinate) int { + top := math.MinInt + for i := range list { + if list[i].Y > top { + top = list[i].Y + } + } + return top +} +func GetLowestY(list ...Coordinate) int { + bot := math.MaxInt + for i := range list { + if list[i].Y < bot { + bot = list[i].Y + } + } + return bot +} +func GetLowestX(list ...Coordinate) int { + bot := math.MaxInt + for i := range list { + if list[i].X < bot { + bot = list[i].X + } + } + return bot +} +func GetHighestX(list ...Coordinate) int { + top := math.MinInt + for i := range list { + if list[i].X > top { + top = list[i].X + } + } + return top +} diff --git a/helpers/growUpCoordinateByteMap.go b/helpers/growUpCoordinateByteMap.go new file mode 100644 index 0000000..685f93e --- /dev/null +++ b/helpers/growUpCoordinateByteMap.go @@ -0,0 +1,112 @@ +package aoc + +import ( + "math" +) + +type GrowUpCoordByteMap struct { + Field map[Coordinate]byte + Height int + Width int + // The Top-Left-most X/Y + // (Low X, High Y) + TLX, TLY int + // The Bottom-Right-most X/Y + // (High X, Low Y) + BRX, BRY int + + // Options for the 'String' method + StringEmptyIsSpace bool + StringEmptyByte byte +} + +func NewGrowUpCoordByteMap() *GrowUpCoordByteMap { + return &GrowUpCoordByteMap{ + Field: make(map[Coordinate]byte), + TLX: math.MaxInt, + TLY: math.MinInt, + BRX: math.MinInt, + BRY: math.MaxInt, + StringEmptyByte: ' ', + } +} + +func (m *GrowUpCoordByteMap) FindAll(b ...byte) []Coordinate { + var ret []Coordinate + for y := m.TLY; y >= m.BRY; y-- { + for x := m.TLX; x <= m.BRX; x++ { + c := Coordinate{X: x, Y: y} + for i := range b { + if m.Get(c) == b[i] { + ret = append(ret, c) + } + } + } + } + return ret +} + +func (m *GrowUpCoordByteMap) Get(pos Coordinate) byte { + if v, ok := m.Field[pos]; ok { + return v + } + return 0 +} +func (m *GrowUpCoordByteMap) Opt(pos Coordinate, def byte) byte { + if v, ok := m.Field[pos]; ok { + return v + } + return def +} +func (m *GrowUpCoordByteMap) Put(pos Coordinate, val byte) { + m.Field[pos] = val + m.Measure() +} +func (m *GrowUpCoordByteMap) PutBytes(bytes [][]byte, at Coordinate) { + for y := range bytes { + for x := range bytes[y] { + m.Put(Coordinate{X: at.X + x, Y: at.Y + y}, bytes[y][x]) + } + } + m.Measure() +} +func (m *GrowUpCoordByteMap) Delete(pos Coordinate) { + delete(m.Field, pos) + m.Measure() +} +func (m *GrowUpCoordByteMap) Measure() { + m.TLX, m.TLY = math.MaxInt, math.MinInt + m.BRX, m.BRY = math.MinInt, math.MaxInt + for c := range m.Field { + if c.X < m.TLX { + m.TLX = c.X + } + if c.Y < m.BRY { + m.BRY = c.Y + } + if c.X > m.BRX { + m.BRX = c.X + } + if c.Y > m.TLY { + m.TLY = c.Y + } + m.Width = m.BRX - m.TLX + 1 + m.Height = m.TLY - m.BRY + 1 + } +} +func (m GrowUpCoordByteMap) String() string { + var ret string + for y := m.TLY; y >= m.BRY; y-- { + for x := m.TLX; x <= m.BRX; x++ { + if m.StringEmptyIsSpace { + ret = ret + string(m.Opt(Coordinate{X: x, Y: y}, m.StringEmptyByte)) + } else { + ret = ret + string(m.Field[Coordinate{X: x, Y: y}]) + } + } + if y > m.BRY { + ret = ret + "\n" + } + } + return ret +}