package main import ( "bufio" "fmt" "log" "os" "strings" ) type Graph struct { nodes map[string]*Node } type Node struct { name string neighbours []string } func (g *Graph) addNode(location string) { if _, ok := g.nodes[location]; !ok { g.nodes[location] = &Node{location, make([]string, 0)} } } func (g *Graph) addNeighbour(location, neighbourLocation string) { node := g.nodes[location] node.neighbours = append(node.neighbours, neighbourLocation) node = g.nodes[neighbourLocation] node.neighbours = append(node.neighbours, location) } func (g *Graph) walk(n *Node, visited []string, target string, revisited bool) bool { if strings.ToLower(n.name) == n.name { for _, v := range visited { if v == n.name { if revisited || !partTwo { return false } else { revisited = true } } } } visited = append(visited, n.name) if n.name == target { total++ return true } for _, neighbourLocation := range n.neighbours { if neighbourLocation == "start" { continue } node, ok := g.nodes[neighbourLocation] if !ok { return false } g.walk(node, visited, target, revisited) } return false } var total int var partTwo bool func main() { file, err := os.Open("input.txt") if err != nil { log.Fatal(err) } defer file.Close() scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) graph := Graph{make(map[string]*Node)} for scanner.Scan() { line := scanner.Text() path := strings.Split(line, "-") graph.addNode(path[0]) graph.addNode(path[1]) graph.addNeighbour(path[0], path[1]) } start := graph.nodes["start"] visited := []string{} graph.walk(start, visited, "end", false) fmt.Println(total) partTwo, total = true, 0 graph.walk(start, visited, "end", false) fmt.Println(total) }