2022 Day 19 Complete

This commit is contained in:
Brian Buller 2022-12-27 16:32:19 -06:00
parent 15631b3564
commit d940cade58
2 changed files with 343 additions and 212 deletions

View File

@ -2,175 +2,122 @@ package main
import (
"fmt"
"strings"
"time"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
type blueprint struct {
id int
oreBot oreBot
clayBot clayBot
obsidianBot obsidianBot
geodeBot geodeBot
}
type oreBot struct{ oreCost int }
type clayBot struct{ oreCost int }
type obsidianBot struct{ oreCost, clayCost int }
type geodeBot struct{ oreCost, obsidianCost int }
var globalBest = 0
func main() {
blueprints := parseInput(h.StdinToStringSlice())
part1(blueprints)
part2(blueprints)
}
func part1(blueprints []blueprint) {
result := 0
for _, bp := range blueprints {
result += bp.id * search(bp, 0, 0, 0, 24, 1, 0, 0, 0, 0)
globalBest = 0
}
fmt.Println("# Part 1")
fmt.Println(result)
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 part2(blueprints []blueprint) {
if len(blueprints) < 3 {
fmt.Println("# Part 2")
fmt.Println("Error: Not enough Blueprints")
return
}
}
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++
}
result := 1
for i := 0; i < 3; i++ {
result *= search(blueprints[i], 0, 0, 0, 32, 1, 0, 0, 0, 0)
globalBest = 0
}
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])
fmt.Println("# Part 2")
fmt.Println(result)
}
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
}
func search(bp blueprint, ore, clay, obs, time, oreBots, clayBots, obsidianBots, geodeBots, geodes int) int {
if time == 0 || globalBest >= geodes+rangeSum(geodeBots, geodeBots+time-1) {
return 0
}
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 + ". "
}
if oreBots >= bp.geodeBot.oreCost && obsidianBots >= bp.geodeBot.obsidianCost {
return rangeSum(geodeBots, geodeBots+time-1)
}
return ret
oreLimitHit := oreBots >= h.Max(bp.geodeBot.oreCost, h.Max(bp.clayBot.oreCost, bp.obsidianBot.oreCost))
clayLimitHit := clayBots >= bp.obsidianBot.clayCost
obsLimitHit := obsidianBots >= bp.geodeBot.obsidianCost
best := 0
if !oreLimitHit {
best = h.Max(
best,
geodeBots+search(
bp, ore+oreBots, clay+clayBots, obs+obsidianBots,
time-1, oreBots, clayBots, obsidianBots, geodeBots, geodes+geodeBots))
}
if ore >= bp.oreBot.oreCost && !oreLimitHit {
best = h.Max(
best,
geodeBots+search(
bp, ore-bp.oreBot.oreCost+oreBots, clay+clayBots, obs+obsidianBots,
time-1, oreBots+1, clayBots, obsidianBots, geodeBots, geodes+geodeBots))
}
if ore >= bp.clayBot.oreCost && !clayLimitHit {
best = h.Max(
best, geodeBots+search(
bp, ore-bp.clayBot.oreCost+oreBots, clay+clayBots, obs+obsidianBots,
time-1, oreBots, clayBots+1, obsidianBots, geodeBots, geodes+geodeBots))
}
if ore >= bp.obsidianBot.oreCost && clay >= bp.obsidianBot.clayCost && !obsLimitHit {
best = h.Max(
best, geodeBots+search(
bp, ore-bp.obsidianBot.oreCost+oreBots, clay-bp.obsidianBot.clayCost+clayBots, obs+obsidianBots,
time-1, oreBots, clayBots, obsidianBots+1, geodeBots, geodes+geodeBots))
}
if ore >= bp.geodeBot.oreCost && obs >= bp.geodeBot.obsidianCost {
best = h.Max(
best, geodeBots+search(
bp, ore-bp.geodeBot.oreCost+oreBots, clay+clayBots, obs-bp.geodeBot.obsidianCost+obsidianBots,
time-1, oreBots, clayBots, obsidianBots, geodeBots+1, geodes+geodeBots))
}
globalBest = h.Max(best, globalBest)
return best
}
func ParseBlueprints(inp []string) []Blueprint {
var ret []Blueprint
func rangeSum(first, last int) int {
return last*(last+1)/2 - ((first - 1) * first / 2)
}
func parseInput(inp []string) []blueprint {
var ret []blueprint
var id int
oreBot := oreBot{}
clayBot := clayBot{}
obsidianBot := obsidianBot{}
geodeBot := geodeBot{}
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})
fmt.Sscanf(inp[i], "Blueprint %d: Each ore robot costs %d ore. Each clay robot costs %d ore. Each obsidian robot costs %d ore and %d clay. Each geode robot costs %d ore and %d obsidian.", &id, &oreBot.oreCost, &clayBot.oreCost, &obsidianBot.oreCost, &obsidianBot.clayCost, &geodeBot.oreCost, &geodeBot.obsidianCost)
ret = append(ret, blueprint{id, oreBot, clayBot, obsidianBot, geodeBot})
}
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"
}

View File

@ -1,49 +1,27 @@
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!
Advent of Code
br0xen (AoC++) 45*
--- 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?
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.
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.
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.
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.
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.
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:
@ -59,15 +37,13 @@
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.)
(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.
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:
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.
@ -197,23 +173,234 @@
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.
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 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?
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.
Your puzzle answer was 1192.
Answer: _____________________ [ [Submit] ]
--- Part Two ---
You can also [Shareon Twitter Mastodon] this puzzle.
While you were choosing the best blueprint, the elephants found some food on their own, so you're not in as much of a hurry; you figure you
probably have 32 minutes before the wind changes direction again and you'll need to get out of range of the erupting volcano.
Unfortunately, one of the elephants ate most of your blueprint list! Now, only the first three blueprints in your list are intact.
In 32 minutes, the largest number of geodes blueprint 1 (from the example above) can open is 56. 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 ==
1 ore-collecting robot collects 1 ore; you now have 3 ore.
== Minute 4 ==
1 ore-collecting robot collects 1 ore; you now have 4 ore.
== Minute 5 ==
Spend 4 ore to start building an ore-collecting robot.
1 ore-collecting robot collects 1 ore; you now have 1 ore.
The new ore-collecting robot is ready; you now have 2 of them.
== Minute 6 ==
2 ore-collecting robots collect 2 ore; you now have 3 ore.
== Minute 7 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
The new clay-collecting robot is ready; you now have 1 of them.
== Minute 8 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
1 clay-collecting robot collects 1 clay; you now have 1 clay.
The new clay-collecting robot is ready; you now have 2 of them.
== Minute 9 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
2 clay-collecting robots collect 2 clay; you now have 3 clay.
The new clay-collecting robot is ready; you now have 3 of them.
== Minute 10 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
3 clay-collecting robots collect 3 clay; you now have 6 clay.
The new clay-collecting robot is ready; you now have 4 of them.
== Minute 11 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
4 clay-collecting robots collect 4 clay; you now have 10 clay.
The new clay-collecting robot is ready; you now have 5 of them.
== Minute 12 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
5 clay-collecting robots collect 5 clay; you now have 15 clay.
The new clay-collecting robot is ready; you now have 6 of them.
== Minute 13 ==
Spend 2 ore to start building a clay-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
6 clay-collecting robots collect 6 clay; you now have 21 clay.
The new clay-collecting robot is ready; you now have 7 of them.
== Minute 14 ==
Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 14 clay.
The new obsidian-collecting robot is ready; you now have 1 of them.
== Minute 15 ==
2 ore-collecting robots collect 2 ore; you now have 4 ore.
7 clay-collecting robots collect 7 clay; you now have 21 clay.
1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian.
== Minute 16 ==
Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
7 clay-collecting robots collect 7 clay; you now have 14 clay.
1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian.
The new obsidian-collecting robot is ready; you now have 2 of them.
== Minute 17 ==
Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 7 clay.
2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian.
The new obsidian-collecting robot is ready; you now have 3 of them.
== Minute 18 ==
2 ore-collecting robots collect 2 ore; you now have 4 ore.
7 clay-collecting robots collect 7 clay; you now have 14 clay.
3 obsidian-collecting robots collect 3 obsidian; you now have 7 obsidian.
== Minute 19 ==
Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
7 clay-collecting robots collect 7 clay; you now have 7 clay.
3 obsidian-collecting robots collect 3 obsidian; you now have 10 obsidian.
The new obsidian-collecting robot is ready; you now have 4 of them.
== Minute 20 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 3 ore.
7 clay-collecting robots collect 7 clay; you now have 14 clay.
4 obsidian-collecting robots collect 4 obsidian; you now have 7 obsidian.
The new geode-cracking robot is ready; you now have 1 of them.
== Minute 21 ==
Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 7 clay.
4 obsidian-collecting robots collect 4 obsidian; you now have 11 obsidian.
1 geode-cracking robot cracks 1 geode; you now have 1 open geode.
The new obsidian-collecting robot is ready; you now have 5 of them.
== Minute 22 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 14 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.
1 geode-cracking robot cracks 1 geode; you now have 2 open geodes.
The new geode-cracking robot is ready; you now have 2 of them.
== Minute 23 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 21 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.
2 geode-cracking robots crack 2 geodes; you now have 4 open geodes.
The new geode-cracking robot is ready; you now have 3 of them.
== Minute 24 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 2 ore.
7 clay-collecting robots collect 7 clay; you now have 28 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.
3 geode-cracking robots crack 3 geodes; you now have 7 open geodes.
The new geode-cracking robot is ready; you now have 4 of them.
== Minute 25 ==
2 ore-collecting robots collect 2 ore; you now have 4 ore.
7 clay-collecting robots collect 7 clay; you now have 35 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.
4 geode-cracking robots crack 4 geodes; you now have 11 open geodes.
== Minute 26 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 4 ore.
7 clay-collecting robots collect 7 clay; you now have 42 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 8 obsidian.
4 geode-cracking robots crack 4 geodes; you now have 15 open geodes.
The new geode-cracking robot is ready; you now have 5 of them.
== Minute 27 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 4 ore.
7 clay-collecting robots collect 7 clay; you now have 49 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 6 obsidian.
5 geode-cracking robots crack 5 geodes; you now have 20 open geodes.
The new geode-cracking robot is ready; you now have 6 of them.
== Minute 28 ==
2 ore-collecting robots collect 2 ore; you now have 6 ore.
7 clay-collecting robots collect 7 clay; you now have 56 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 11 obsidian.
6 geode-cracking robots crack 6 geodes; you now have 26 open geodes.
== Minute 29 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 6 ore.
7 clay-collecting robots collect 7 clay; you now have 63 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.
6 geode-cracking robots crack 6 geodes; you now have 32 open geodes.
The new geode-cracking robot is ready; you now have 7 of them.
== Minute 30 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 6 ore.
7 clay-collecting robots collect 7 clay; you now have 70 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.
7 geode-cracking robots crack 7 geodes; you now have 39 open geodes.
The new geode-cracking robot is ready; you now have 8 of them.
== Minute 31 ==
Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
2 ore-collecting robots collect 2 ore; you now have 6 ore.
7 clay-collecting robots collect 7 clay; you now have 77 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.
8 geode-cracking robots crack 8 geodes; you now have 47 open geodes.
The new geode-cracking robot is ready; you now have 9 of them.
== Minute 32 ==
2 ore-collecting robots collect 2 ore; you now have 8 ore.
7 clay-collecting robots collect 7 clay; you now have 84 clay.
5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.
9 geode-cracking robots crack 9 geodes; you now have 56 open geodes.
However, blueprint 2 from the example above is still better; using it, the largest number of geodes you could open in 32 minutes is 62.
You no longer have enough blueprints to worry about quality levels. Instead, for each of the first three blueprints, determine the largest
number of geodes you could open; then, multiply these three values together.
Don't worry about quality levels; instead, just determine the largest number of geodes you could open using each of the first three
blueprints. What do you get if you multiply these numbers together?
Your puzzle answer was 14725.
Both parts of this puzzle are complete! They provide two gold stars: **
References
@ -221,7 +408,6 @@ References
. 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
@ -233,8 +419,6 @@ References
. 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
. 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);