Skip to content

Instantly share code, notes, and snippets.

@almendar
Created December 12, 2021 09:52
Show Gist options
  • Save almendar/8b8cdfa3dd5603af4d6914dce829d8ee to your computer and use it in GitHub Desktop.
Save almendar/8b8cdfa3dd5603af4d6914dce829d8ee to your computer and use it in GitHub Desktop.
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