You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
1.8 KiB
Go
95 lines
1.8 KiB
Go
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)
|
|
}
|