diff --git a/day16/day16.go b/day16/day16.go index 6b33c8e..b947746 100644 --- a/day16/day16.go +++ b/day16/day16.go @@ -15,15 +15,20 @@ type Valve struct { before string } +type Route struct { + activeValves []string + remainingTime int + remainingValves []string + pastMoves []string + releasedPressure int +} + func main() { //args := os.Args[1:] - lines := helper.ReadTextFile("day16/testinput") + lines := helper.ReadTextFile("day16/input") valves := getValves(lines) - startValve := "AA" valvesWithFlowRate := getValvesWithFlowRate(valves) valvesWithFlowRate = append(valvesWithFlowRate, "AA") - fmt.Println(startValve) - fmt.Println(valvesWithFlowRate) valvesCopy := deepCopyMap(valves) for i, activeValve := range valvesWithFlowRate { routes := make(map[string]int) @@ -40,10 +45,30 @@ func main() { } currentValve := "AA" remainingValves := valvesWithFlowRate[:len(valvesWithFlowRate)-1] + activeRountes := []Route{Route{[]string{currentValve}, 30, remainingValves, []string{}, 0}} + endedRoutes := []Route{} + for len(activeRountes) > 0 { + stepFindSolution(&valves, &activeRountes, &endedRoutes) + } + highestPressureRelease := 0 + for _, route := range endedRoutes { + if route.releasedPressure > highestPressureRelease { + highestPressureRelease = route.releasedPressure + } + } + fmt.Println(highestPressureRelease) +} + +func falseSolutionPart1(currentValve string, remainingValves []string, valves map[string]Valve) { + fmt.Println(currentValve) + fmt.Println(remainingValves) remainingTime := 30 sumReleasedPressure := 0 - getNextStep(&remainingValves, valves, ¤tValve, &remainingTime, &sumReleasedPressure) - fmt.Println(currentValve) + for len(remainingValves) > 0 && remainingTime > 0 { + getNextStep(&remainingValves, valves, ¤tValve, &remainingTime, &sumReleasedPressure) + fmt.Println(currentValve) + } + fmt.Println(sumReleasedPressure) } func getNextStep(remainingValves *[]string, valves map[string]Valve, currentValve *string, remainingTime *int, sumReleasedPressure *int) { @@ -59,12 +84,43 @@ func getNextStep(remainingValves *[]string, valves map[string]Valve, currentValv bestValve = i } } + if bestValve == -1 { + *remainingTime = 0 + return + } *sumReleasedPressure += bestValue *remainingTime -= (valves[*currentValve].routes[(*remainingValves)[bestValve]] + 1) *currentValve = (*remainingValves)[bestValve] helper.Remove(remainingValves, bestValve) } +func stepFindSolution(valves *map[string]Valve, remainingRoutes *[]Route, endedRoutes *[]Route) { + currentRoute := (*remainingRoutes)[len(*remainingRoutes)-1] + *remainingRoutes = (*remainingRoutes)[:len(*remainingRoutes)-1] + + directions := make(map[string]int) + for _, remainingValve := range currentRoute.remainingValves { + movingTimeCost := (*valves)[currentRoute.activeValves[0]].routes[remainingValve] + openingTimeCost := 1 + if currentRoute.remainingTime > movingTimeCost+openingTimeCost { + directions[remainingValve] = movingTimeCost + openingTimeCost + } + } + if len(directions) == 0 { + *endedRoutes = append(*endedRoutes, currentRoute) + } + + for remainingValve, timeCost := range directions { + flowrate := (*valves)[remainingValve].flowRate + newRemainingTime := currentRoute.remainingTime - timeCost + newRemainingValves := helper.RemoveElement(currentRoute.remainingValves, remainingValve) + possibleGainedPressureReduction := newRemainingTime * flowrate + newReleasedPressure := currentRoute.releasedPressure + possibleGainedPressureReduction + newPastMoves := append(currentRoute.pastMoves, remainingValve) + *remainingRoutes = append(*remainingRoutes, Route{[]string{remainingValve}, newRemainingTime, newRemainingValves, newPastMoves, newReleasedPressure}) + } +} + func deepCopyMap(valves map[string]Valve) map[string]Valve { tmpValves := make(map[string]Valve) for k, v := range valves { @@ -117,6 +173,17 @@ func step(valves *map[string]Valve, activeValves *map[string]struct{}) { currentValve := (*valves)[valve] currentFieldSumCost := currentValve.cost directions := currentValve.routes + for _, v := range *valves { + lenthConnectionToCurrentValve := 0 + for connectedValve, length := range v.routes { + if connectedValve == currentValve.id { + lenthConnectionToCurrentValve = length + } + } + if lenthConnectionToCurrentValve > 0 { + directions[v.id] = lenthConnectionToCurrentValve + } + } for nextValve, _ := range directions { cost := 1 + currentFieldSumCost if nextValve != currentValve.before { diff --git a/helper/helper.go b/helper/helper.go index 496c26a..873e04d 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -103,6 +103,16 @@ func Remove[T any](s *[]T, i int) { *s = (*s)[:len(*s)-1] } +func RemoveElement[T constraints.Ordered](s []T, i T) []T { + newS := []T{} + for _, val := range s { + if val != i { + newS = append(newS, val) + } + } + return newS +} + func GetValueOf2DMap[T any](location [2]int, map2D *[][]T) (T, error) { if location[0] >= len(*map2D) { return (*map2D)[0][0], errors.New("First location value too big")