Created
December 12, 2021 09:52
-
-
Save almendar/8b8cdfa3dd5603af4d6914dce829d8ee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io/ioutil" | |
"log" | |
"strings" | |
) | |
func readInput(input string) map[string][]string { | |
bytes, err := ioutil.ReadFile(input) | |
if err != nil { | |
log.Fatal(err) | |
} | |
ret := make(map[string][]string) | |
for _, line := range strings.Split(string(bytes), "\n") { | |
x := strings.Split(line, "-") | |
c1 := x[0] | |
c2 := x[1] | |
add := func(from string, to string) { | |
// fmt.Printf("%s-%s\n", from, to) | |
if from != "end" && to != "start" { | |
val, ok := ret[from] | |
if !ok { | |
ret[from] = make([]string, 0) | |
} | |
val = append(val, to) | |
ret[from] = val | |
} | |
} | |
add(c1, c2) | |
add(c2, c1) | |
} | |
return ret | |
} | |
func visitOnlyOnceIfLowercase(item string, path []string) bool { | |
if strings.ToLower(item) == item && contains(item, path) { | |
return false | |
} | |
return true | |
} | |
func lowerCaseMaxTwice(item string, path []string) bool { | |
counts := make(map[string]int) | |
wasTwice := false | |
for _, v := range path { | |
if strings.ToLower(v) == v { | |
counts[v]++ | |
if counts[v] == 2 { | |
wasTwice = true | |
} | |
} | |
} | |
if wasTwice { | |
return counts[item] == 0 | |
} else { | |
return counts[item] < 2 | |
} | |
} | |
func step(paths map[string][]string, node string, path []string, | |
validMove func(string, []string) bool) int { | |
count := 0 | |
moves := paths[node] | |
for _, v := range moves { | |
//check if valid move | |
if !validMove(v, path) { | |
continue | |
} | |
if v == "end" { | |
wholePath := make([]string, len(path)) | |
copy(wholePath, path) | |
wholePath = append(wholePath, v) | |
count += 1 | |
} else { | |
pathHere := make([]string, len(path)) | |
copy(pathHere, path) | |
pathHere = append(pathHere, v) | |
count += step(paths, v, pathHere, validMove) | |
} | |
} | |
return count | |
} | |
func contains(s string, list []string) bool { | |
for _, v := range list { | |
if v == s { | |
return true | |
} | |
} | |
return false | |
} | |
func task1(input string) { | |
paths := readInput(input) | |
numberOfPaths := step(paths, "start", []string{"start"}, visitOnlyOnceIfLowercase) | |
fmt.Printf("Day12 task1 %s - %d\n", input, numberOfPaths) | |
} | |
func task2(input string) { | |
paths := readInput(input) | |
numberOfPaths := step(paths, "start", []string{"start"}, lowerCaseMaxTwice) | |
fmt.Printf("Day12 task1 %s - %d\n", input, numberOfPaths) | |
} | |
func main() { | |
// fmt.Printf("%+v", paths) | |
task1("example1.txt") | |
task1("example2.txt") | |
task1("example3.txt") | |
task1("input.txt") | |
task2("example1.txt") | |
task2("example2.txt") | |
task2("example3.txt") | |
task2("input.txt") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment