Zwischenstand
This commit is contained in:
parent
367e5eda0f
commit
7ed45eb39a
191
day19/day19.go
Normal file
191
day19/day19.go
Normal file
@ -0,0 +1,191 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"AOC2022/helper"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type State struct {
|
||||
currentRessources [4]int
|
||||
currentProduction [4]int
|
||||
runtime int
|
||||
}
|
||||
|
||||
type Blueprint struct {
|
||||
oreRoboterCost int
|
||||
clayRoboterCost int
|
||||
obsidianRobototerCost [2]int
|
||||
geodeRoboterCost [2]int
|
||||
}
|
||||
|
||||
func main() {
|
||||
//args := os.Args[1:]
|
||||
lines := helper.ReadTextFile("day19/input")
|
||||
highestGeode := make([]int, len(lines))
|
||||
for i, line := range lines {
|
||||
blueprint := getBluePrint(line)
|
||||
startStates := []State{State{[4]int{0, 0, 0, 0}, [4]int{1, 0, 0, 0}, 0}}
|
||||
fastestTime := getFastestTimeToElementN(blueprint, []State{State{[4]int{0, 0, 0, 0}, [4]int{1, 0, 0, 0}, 0}}, 2)
|
||||
startStates = getAllPossibleCombinationsWithFastestTime(blueprint, []State{State{[4]int{0, 0, 0, 0}, [4]int{1, 0, 0, 0}, 0}}, 2, fastestTime)
|
||||
tmpStates := getAllPossibleCombinationsWithFastestTime(blueprint, []State{State{[4]int{0, 0, 0, 0}, [4]int{1, 0, 0, 0}, 0}}, 2, fastestTime)
|
||||
fastestTime = getFastestTimeToElementN(blueprint, tmpStates, 3)
|
||||
startStates = getAllPossibleCombinationsWithFastestTime(blueprint, startStates, 3, fastestTime)
|
||||
highestGeode[i] = getHighestGeode(blueprint, startStates)
|
||||
}
|
||||
sum := 0
|
||||
for i, score := range highestGeode {
|
||||
sum += (i + 1) * score
|
||||
}
|
||||
fmt.Println(sum)
|
||||
|
||||
}
|
||||
|
||||
func getHighestGeode(blueprint Blueprint, startStates []State) int {
|
||||
activeStates := startStates
|
||||
endStates := []State{}
|
||||
for len(activeStates) > 0 {
|
||||
stepHighestGeode(&activeStates, &endStates, &blueprint)
|
||||
}
|
||||
highestgeode := 0
|
||||
for _, state := range endStates {
|
||||
if state.currentRessources[3] > highestgeode && state.runtime < 25 {
|
||||
highestgeode = state.currentRessources[3]
|
||||
}
|
||||
}
|
||||
return highestgeode
|
||||
}
|
||||
|
||||
func getFastestTimeToElementN(blueprint Blueprint, startStates []State, untilElementN int) int {
|
||||
activeStates := startStates
|
||||
fastestTimeToObsidianState := State{[4]int{0, 0, 0, 0}, [4]int{1, 0, 0, 0}, 26}
|
||||
for len(activeStates) > 0 {
|
||||
step(&activeStates, &fastestTimeToObsidianState, untilElementN, &blueprint)
|
||||
}
|
||||
return fastestTimeToObsidianState.runtime
|
||||
}
|
||||
|
||||
func getAllPossibleCombinationsWithFastestTime(blueprint Blueprint, startStates []State, untilElementN int, fastestTime int) []State {
|
||||
activeStates := startStates
|
||||
fastestTimeToObsidianState := map[[8]int]State{}
|
||||
for len(activeStates) > 0 {
|
||||
stepFindAllFastestTime(&activeStates, &fastestTimeToObsidianState, untilElementN, fastestTime, &blueprint)
|
||||
}
|
||||
returnStates := []State{}
|
||||
for _, val := range fastestTimeToObsidianState {
|
||||
returnStates = append(returnStates, val)
|
||||
}
|
||||
return returnStates
|
||||
}
|
||||
|
||||
func step(activeStates *[]State, fastestTImeToObsidian *State, untilElementN int, blueprint *Blueprint) {
|
||||
activeStates, newTmpStates := generatePossibleTmpStates(activeStates, blueprint)
|
||||
for _, tmpState := range newTmpStates {
|
||||
if tmpState.currentProduction[untilElementN] > 0 && (*fastestTImeToObsidian).runtime > tmpState.runtime {
|
||||
*fastestTImeToObsidian = tmpState
|
||||
}
|
||||
if tmpState.currentProduction[untilElementN] == 0 && tmpState.runtime < (*fastestTImeToObsidian).runtime {
|
||||
*activeStates = append(*activeStates, tmpState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stepHighestGeode(activeStates *[]State, endStates *[]State, blueprint *Blueprint) {
|
||||
activeStates, newTmpStates := generatePossibleTmpStates(activeStates, blueprint)
|
||||
for _, tmpState := range newTmpStates {
|
||||
if tmpState.runtime < 24 {
|
||||
*activeStates = append(*activeStates, tmpState)
|
||||
} else {
|
||||
*endStates = append(*endStates, tmpState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stepFindAllFastestTime(activeStates *[]State, fastestTImeStates *map[[8]int]State, untilElementN int, fastestTime int, blueprint *Blueprint) {
|
||||
activeStates, newTmpStates := generatePossibleTmpStates(activeStates, blueprint)
|
||||
for _, tmpState := range newTmpStates {
|
||||
if tmpState.currentProduction[untilElementN] > 0 && fastestTime >= tmpState.runtime {
|
||||
identifier := [8]int{}
|
||||
copy(identifier[:], append(tmpState.currentRessources[:], tmpState.currentProduction[:]...)[:8])
|
||||
(*fastestTImeStates)[identifier] = tmpState
|
||||
}
|
||||
if tmpState.currentProduction[untilElementN] == 0 && tmpState.runtime < fastestTime {
|
||||
*activeStates = append(*activeStates, tmpState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generatePossibleTmpStates(activeStates *[]State, blueprint *Blueprint) (*[]State, []State) {
|
||||
activeState := (*activeStates)[len(*activeStates)-1]
|
||||
*activeStates = (*activeStates)[:len(*activeStates)-1]
|
||||
possibleProductions := activeState.getPossibleProductions(blueprint)
|
||||
newTmpStates := []State{}
|
||||
for i := -1; i < len(possibleProductions); i++ {
|
||||
if i == -1 || possibleProductions[i] == 1 {
|
||||
tmpState := activeState
|
||||
tmpState.produceRessources()
|
||||
tmpState.produceRoboter(blueprint, i)
|
||||
tmpState.runtime++
|
||||
newTmpStates = append(newTmpStates, tmpState)
|
||||
}
|
||||
}
|
||||
return activeStates, newTmpStates
|
||||
}
|
||||
|
||||
func (state *State) produceRoboter(blueprint *Blueprint, roboter int) {
|
||||
switch roboter {
|
||||
case 0:
|
||||
state.currentProduction[0]++
|
||||
state.currentRessources[0] -= blueprint.oreRoboterCost
|
||||
case 1:
|
||||
state.currentProduction[1]++
|
||||
state.currentRessources[0] -= blueprint.clayRoboterCost
|
||||
case 2:
|
||||
state.currentProduction[2]++
|
||||
state.currentRessources[0] -= blueprint.obsidianRobototerCost[0]
|
||||
state.currentRessources[1] -= blueprint.obsidianRobototerCost[1]
|
||||
case 3:
|
||||
state.currentProduction[3]++
|
||||
state.currentRessources[0] -= blueprint.geodeRoboterCost[0]
|
||||
state.currentRessources[2] -= blueprint.geodeRoboterCost[1]
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (state *State) produceRessources() {
|
||||
for i := 0; i < 4; i++ {
|
||||
state.currentRessources[i] += state.currentProduction[i]
|
||||
}
|
||||
}
|
||||
|
||||
func (state State) getPossibleProductions(blueprint *Blueprint) [4]int {
|
||||
possibleProductions := [4]int{0, 0, 0, 0}
|
||||
if state.currentRessources[0] >= blueprint.oreRoboterCost {
|
||||
possibleProductions[0] = 1
|
||||
}
|
||||
if state.currentRessources[0] >= blueprint.clayRoboterCost {
|
||||
possibleProductions[1] = 1
|
||||
}
|
||||
if state.currentRessources[0] >= blueprint.obsidianRobototerCost[0] && state.currentRessources[1] >= blueprint.obsidianRobototerCost[1] {
|
||||
possibleProductions[2] = 1
|
||||
}
|
||||
if state.currentRessources[0] >= blueprint.geodeRoboterCost[0] && state.currentRessources[2] >= blueprint.geodeRoboterCost[1] {
|
||||
possibleProductions[3] = 1
|
||||
}
|
||||
return possibleProductions
|
||||
}
|
||||
|
||||
func getBluePrint(line string) Blueprint {
|
||||
productionCostStrings := strings.Split(strings.Split(line, ":")[1], ". ")
|
||||
oreCostString := strings.ReplaceAll(productionCostStrings[0], " ore", "")[18:]
|
||||
oreCost, _ := strconv.Atoi(oreCostString)
|
||||
clayCostString := strings.ReplaceAll(productionCostStrings[1], " ore", "")[22:]
|
||||
claycost, _ := strconv.Atoi(clayCostString)
|
||||
obsidiancostString := strings.ReplaceAll(productionCostStrings[2], "ore and ", "")[26:]
|
||||
obsidianCost := helper.StringSliceToIntSlice(strings.Split(obsidiancostString[:len(obsidiancostString)-5], " "))
|
||||
geodeCostString := strings.ReplaceAll(productionCostStrings[3], "ore and ", "")[23:]
|
||||
geodeCost := helper.StringSliceToIntSlice(strings.Split(geodeCostString[:len(geodeCostString)-10], " "))
|
||||
return Blueprint{oreCost, claycost, [2]int{obsidianCost[0], obsidianCost[1]}, [2]int{geodeCost[0], geodeCost[1]}}
|
||||
}
|
30
day19/input
Normal file
30
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 4 ore and 14 clay. Each geode robot costs 2 ore and 16 obsidian.
|
||||
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||
Blueprint 3: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||
Blueprint 4: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.
|
||||
Blueprint 5: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 2 ore and 10 obsidian.
|
||||
Blueprint 6: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 4 ore and 8 obsidian.
|
||||
Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 9 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 8: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 3 ore and 14 obsidian.
|
||||
Blueprint 9: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 3 ore and 18 obsidian.
|
||||
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 16 obsidian.
|
||||
Blueprint 11: 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 3 ore and 15 obsidian.
|
||||
Blueprint 12: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 8 obsidian.
|
||||
Blueprint 13: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 17 obsidian.
|
||||
Blueprint 14: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 3 ore and 10 obsidian.
|
||||
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 4 ore and 20 obsidian.
|
||||
Blueprint 16: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 20 obsidian.
|
||||
Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 3 ore and 15 obsidian.
|
||||
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 3 ore and 13 obsidian.
|
||||
Blueprint 19: 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 20: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 9 obsidian.
|
||||
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 20 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 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 4 ore and 11 obsidian.
|
||||
Blueprint 24: 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 25: 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 26: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 4 ore and 16 obsidian.
|
||||
Blueprint 27: 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 4 ore and 11 obsidian.
|
||||
Blueprint 28: 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 29: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 3 ore and 14 obsidian.
|
||||
Blueprint 30: 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.
|
2
day19/testinput
Normal file
2
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.
|
Loading…
Reference in New Issue
Block a user