2022 Day 17 part 1 Complete
This commit is contained in:
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"
|
||||
}
|
||||
Reference in New Issue
Block a user