Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "bufio"
- "fmt"
- "os"
- "time"
- )
- func main() {
- // contents, err := LoadNewlineSeparatedStrings("testinput")
- start := time.Now()
- contents, err := LoadNewlineSeparatedStrings("input")
- loadDone := time.Since(start)
- if err != nil {
- panic(err)
- }
- PartOne(contents)
- p1Done := time.Since(start)
- PartTwo(contents)
- p2Done := time.Since(start)
- fmt.Printf("finished in %v\t(load file: %v\tp1: %v\tp2: %v)\n", time.Since(start), loadDone.Sub(start), p1Done.Sub(loadDone), p2Done.Sub(p1Done))
- }
- type node struct {
- level int
- neighbors []*node
- }
- func parseContents(contents []string) []*node {
- startNodes := make([]*node, 0)
- nodeMatrix := make([][]*node, 0)
- for _, row := range contents {
- nodes := make([]*node, 0)
- for _, col := range row {
- level := int(col) - 48
- nodes = append(nodes, &node{
- level: level,
- neighbors: make([]*node, 0),
- })
- }
- nodeMatrix = append(nodeMatrix, nodes)
- }
- for i := range nodeMatrix {
- for j := range nodeMatrix[i] {
- n := nodeMatrix[i][j]
- if n.level == 0 {
- startNodes = append(startNodes, n)
- }
- if i > 0 && nodeMatrix[i-1][j].level == n.level+1 {
- n.neighbors = append(n.neighbors, nodeMatrix[i-1][j])
- }
- if i < len(nodeMatrix)-1 && nodeMatrix[i+1][j].level == n.level+1 {
- n.neighbors = append(n.neighbors, nodeMatrix[i+1][j])
- }
- if j > 0 && nodeMatrix[i][j-1].level == n.level+1 {
- n.neighbors = append(n.neighbors, nodeMatrix[i][j-1])
- }
- if j < len(nodeMatrix)-1 && nodeMatrix[i][j+1].level == n.level+1 {
- n.neighbors = append(n.neighbors, nodeMatrix[i][j+1])
- }
- }
- }
- return startNodes
- }
- func PartOne(contents []string) {
- startingPoints := parseContents(contents)
- trailHeads := 0
- for _, n := range startingPoints {
- trailHeads += len(countTrailheads(n))
- }
- fmt.Printf("total trailheads: %d\n", trailHeads)
- }
- func countTrailheads(n *node) map[*node]int {
- toVisit := make([]*node, 0)
- toVisit = append(toVisit, n.neighbors...)
- trailHeads := make(map[*node]int)
- for len(toVisit) > 0 {
- head := toVisit[0]
- toVisit = toVisit[1:]
- if head.level == 9 {
- if _, exists := trailHeads[head]; !exists {
- trailHeads[head] = 0
- }
- trailHeads[head] += 1
- } else {
- toVisit = append(toVisit, head.neighbors...)
- }
- }
- return trailHeads
- }
- func PartTwo(contents []string) {
- startingPoints := parseContents(contents)
- rating := 0
- for _, n := range startingPoints {
- trailHeadRatings := countTrailheads(n)
- for _, v := range trailHeadRatings {
- rating += v
- }
- }
- fmt.Printf("total trailhead ratings: %d\n", rating)
- }
- func LoadNewlineSeparatedStrings(path string) ([]string, error) {
- file, err := os.OpenFile(path, os.O_RDONLY, 0644)
- if err != nil {
- return nil, fmt.Errorf("load newline separated strings: %w", err)
- }
- defer file.Close()
- rows := make([]string, 0)
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- rows = append(rows, scanner.Text())
- }
- if err := scanner.Err(); err != nil {
- return nil, fmt.Errorf("load newline separated strings: %w", err)
- }
- return rows, nil
- }
Advertisement
Add Comment
Please, Sign In to add comment