diff --git a/day16/day16.go b/day16/day16.go index b947746..668c6ac 100644 --- a/day16/day16.go +++ b/day16/day16.go @@ -16,8 +16,8 @@ type Valve struct { } type Route struct { - activeValves []string - remainingTime int + activeValves [2]string + remainingTime [2]int remainingValves []string pastMoves []string releasedPressure int @@ -45,7 +45,12 @@ func main() { } currentValve := "AA" remainingValves := valvesWithFlowRate[:len(valvesWithFlowRate)-1] - activeRountes := []Route{Route{[]string{currentValve}, 30, remainingValves, []string{}, 0}} + part2(currentValve, remainingValves, valves) + +} + +func part1(currentValve string, remainingValves []string, valves map[string]Valve) { + activeRountes := []Route{Route{[2]string{currentValve}, [2]int{30}, remainingValves, []string{}, 0}} endedRoutes := []Route{} for len(activeRountes) > 0 { stepFindSolution(&valves, &activeRountes, &endedRoutes) @@ -59,6 +64,22 @@ func main() { fmt.Println(highestPressureRelease) } +func part2(currentValve string, remainingValves []string, valves map[string]Valve) { + activeRountes := []Route{Route{[2]string{currentValve, currentValve}, [2]int{26, 26}, remainingValves, []string{}, 0}} + endedRoutes := []Route{} + for len(activeRountes) > 0 { + stepFindSolution(&valves, &activeRountes, &endedRoutes) + } + highestPressureReleaseRoute := Route{} + highestPressureReleaseRoute.releasedPressure = 0 + for _, route := range endedRoutes { + if route.releasedPressure > highestPressureReleaseRoute.releasedPressure { + highestPressureReleaseRoute = route + } + } + fmt.Println(highestPressureReleaseRoute.releasedPressure) +} + func falseSolutionPart1(currentValve string, remainingValves []string, valves map[string]Valve) { fmt.Println(currentValve) fmt.Println(remainingValves) @@ -98,27 +119,79 @@ func stepFindSolution(valves *map[string]Valve, remainingRoutes *[]Route, endedR 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 + directions1 := getDirections(valves, currentRoute.remainingValves, currentRoute.activeValves[0], currentRoute.remainingTime[0]) + directions2 := getDirections(valves, currentRoute.remainingValves, currentRoute.activeValves[1], currentRoute.remainingTime[1]) + directionPairs := [][2]map[string]int{} + for valve1, cost1 := range directions1 { + if len(directions2) == 0 { + direction1 := map[string]int{valve1: cost1} + directionPairs = append(directionPairs, [2]map[string]int{direction1}) + } + for valve2, cost2 := range directions2 { + if valve1 != valve2 { + direction1 := map[string]int{valve1: cost1} + direction2 := map[string]int{valve2: cost2} + directionPairs = append(directionPairs, [2]map[string]int{direction1, direction2}) + } } } - if len(directions) == 0 { + if len(directionPairs) == 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}) + for _, pair := range directionPairs { + newRoute := Route{} + newPastMoves := currentRoute.pastMoves + newReleasedPressure := currentRoute.releasedPressure + newRemainingValves := currentRoute.remainingValves + for remainingValve, timeCost := range pair[0] { + newRemainingTime1, possibleGainedPressureReduction1 := getNewTimeAndRemainingValves(valves, remainingValve, currentRoute, timeCost) + newReleasedPressure += possibleGainedPressureReduction1 + newPastMoves = append(newPastMoves, remainingValve) + newRemainingValves = helper.RemoveElement(newRemainingValves, remainingValve) + newRoute.remainingTime[0] = newRemainingTime1 + newRoute.activeValves[0] = remainingValve + } + for remainingValve, timeCost := range pair[1] { + newRemainingTime2, possibleGainedPressureReduction2 := getNewTimeAndRemainingValves(valves, remainingValve, currentRoute, timeCost) + newReleasedPressure += possibleGainedPressureReduction2 + newPastMoves = append(newPastMoves, remainingValve) + newRemainingValves = helper.RemoveElement(newRemainingValves, remainingValve) + newRoute.remainingTime[1] = newRemainingTime2 + newRoute.activeValves[1] = remainingValve + } + newRoute.pastMoves = newPastMoves + newRoute.releasedPressure = newReleasedPressure + newRoute.remainingValves = newRemainingValves + *remainingRoutes = append(*remainingRoutes, newRoute) } + + //for remainingValve, timeCost := range directions1 { + // newRemainingTime, possibleGainedPressureReduction := getNewTimeAndRemainingValves(valves, remainingValve, currentRoute, timeCost) + // newRemainingValves := helper.RemoveElement(currentRoute.remainingValves, remainingValve) + // newReleasedPressure := currentRoute.releasedPressure + possibleGainedPressureReduction + // newPastMoves := append(currentRoute.pastMoves, remainingValve) + // *remainingRoutes = append(*remainingRoutes, Route{[2]string{remainingValve}, [2]int{newRemainingTime}, newRemainingValves, newPastMoves, newReleasedPressure}) + //} +} + +func getNewTimeAndRemainingValves(valves *map[string]Valve, remainingValve string, currentRoute Route, timeCost int) (int, int) { + flowrate := (*valves)[remainingValve].flowRate + newRemainingTime := currentRoute.remainingTime[0] - timeCost + possibleGainedPressureReduction := newRemainingTime * flowrate + return newRemainingTime, possibleGainedPressureReduction +} + +func getDirections(valves *map[string]Valve, remainingValves []string, activeValve string, remainingTime int) map[string]int { + directions := make(map[string]int) + for _, remainingValve := range remainingValves { + movingTimeCost := (*valves)[activeValve].routes[remainingValve] + openingTimeCost := 1 + if remainingTime > movingTimeCost+openingTimeCost { + directions[remainingValve] = movingTimeCost + openingTimeCost + } + } + return directions } func deepCopyMap(valves map[string]Valve) map[string]Valve {