177 lines
3.6 KiB
Go
177 lines
3.6 KiB
Go
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"
|
|
}
|