2022 Day 17 part 1 Complete
This commit is contained in:
parent
4abc58d07d
commit
c4d5dae456
1
2022/day17/input
Normal file
1
2022/day17/input
Normal file
File diff suppressed because one or more lines are too long
294
2022/day17/main.go
Normal file
294
2022/day17/main.go
Normal file
@ -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 " "
|
||||||
|
}
|
404
2022/day17/problem
Normal file
404
2022/day17/problem
Normal file
@ -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);
|
1
2022/day17/testinput
Normal file
1
2022/day17/testinput
Normal file
@ -0,0 +1 @@
|
|||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
30
2022/day19/input
Normal file
30
2022/day19/input
Normal file
@ -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.
|
176
2022/day19/main.go
Normal file
176
2022/day19/main.go
Normal file
@ -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"
|
||||||
|
}
|
240
2022/day19/problem
Normal file
240
2022/day19/problem
Normal file
@ -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);
|
2
2022/day19/testinput
Normal file
2
2022/day19/testinput
Normal file
@ -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.
|
@ -134,3 +134,40 @@ func (c Coordinate) Adjacent(c2 Coordinate) bool {
|
|||||||
c2.Equals(c.West()) ||
|
c2.Equals(c.West()) ||
|
||||||
c2.Equals(c.NW())
|
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
|
||||||
|
}
|
||||||
|
112
helpers/growUpCoordinateByteMap.go
Normal file
112
helpers/growUpCoordinateByteMap.go
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user