103 lines
2.6 KiB
Go
103 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2021/src/helper"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
type pathTracking struct {
|
|
route []string
|
|
visitedSmallCaveTwice bool
|
|
}
|
|
|
|
type stepTracking struct {
|
|
destiny string
|
|
visitedSmallCaveTwice bool
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
input2, err := helper.GetInput("day12TestPart2Routes.txt")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
testRoutesPart2 := make([][]string, 0)
|
|
for _, line := range input2 {
|
|
splitLine := strings.Split(line, ",")
|
|
testRoutesPart2 = append(testRoutesPart2, splitLine)
|
|
}
|
|
|
|
routeMap := make(map[string][]string)
|
|
for _, line := range input {
|
|
splitLine := strings.Split(line, "-")
|
|
if splitLine[0] != "start" && splitLine[1] != "end" {
|
|
routeMap[splitLine[1]] = append(routeMap[splitLine[1]], splitLine[0])
|
|
}
|
|
routeMap[splitLine[0]] = append(routeMap[splitLine[0]], splitLine[1])
|
|
}
|
|
for key, val := range routeMap {
|
|
fmt.Printf("%s : %s \n", key, val)
|
|
}
|
|
|
|
//part1
|
|
allRoutesCounter := 0
|
|
getRoute(&routeMap, []string{"start"}, &allRoutesCounter, 1, &testRoutesPart2)
|
|
fmt.Println(allRoutesCounter)
|
|
|
|
//part2
|
|
allRoutesCounter = 0
|
|
getRoute(&routeMap, []string{"start"}, &allRoutesCounter, 2, &testRoutesPart2)
|
|
fmt.Println(allRoutesCounter)
|
|
fmt.Println(len(testRoutesPart2))
|
|
fmt.Println()
|
|
for _, route := range testRoutesPart2 {
|
|
fmt.Println(route)
|
|
}
|
|
|
|
}
|
|
|
|
func getRoute(routeMap *map[string][]string, drivenRoute []string, allRoutesCounter *int, part int, testRoutesPart2 *[][]string) {
|
|
if drivenRoute[len(drivenRoute)-1] == "end" {
|
|
*allRoutesCounter++
|
|
for i, route := range *testRoutesPart2 {
|
|
if helper.EqualStringArray(route, drivenRoute) {
|
|
*testRoutesPart2 = append((*testRoutesPart2)[:i], (*testRoutesPart2)[i+1:]...)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
position := drivenRoute[len(drivenRoute)-1]
|
|
possibleNextSteps := []string{}
|
|
for _, step := range (*routeMap)[position] {
|
|
if !unicode.IsLower(rune(step[0])) || !(helper.ContainsString(step, drivenRoute) > 0) {
|
|
possibleNextSteps = append(possibleNextSteps, step)
|
|
} else if part == 2 && !checkRouteForDoubleVisitedSmallCaves(drivenRoute) {
|
|
possibleNextSteps = append(possibleNextSteps, step)
|
|
}
|
|
}
|
|
|
|
for _, step := range possibleNextSteps {
|
|
newDrivenRoute := append(drivenRoute, step)
|
|
getRoute(routeMap, newDrivenRoute, allRoutesCounter, part, testRoutesPart2)
|
|
}
|
|
}
|
|
|
|
func checkRouteForDoubleVisitedSmallCaves(route []string) bool {
|
|
smallCavesCounter := make(map[string]int)
|
|
for _, step := range route {
|
|
if unicode.IsLower(rune(step[0])) && step != "end" {
|
|
smallCavesCounter[step]++
|
|
if smallCavesCounter[step] > 1 {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|