AoC2021/src/day12/day12.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
}