Skip to content

Instantly share code, notes, and snippets.

@MarcoBuster
Created December 7, 2020 09:50
Show Gist options
  • Save MarcoBuster/652f4ce321638a798fa17f3b2f460be2 to your computer and use it in GitHub Desktop.
Save MarcoBuster/652f4ce321638a798fa17f3b2f460be2 to your computer and use it in GitHub Desktop.
(Bonus) alternative solution for the first part of AoC2020 day 7
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Rule struct {
content string
quantity int
}
type RuleGraph struct {
nodes []*Rule
edges map[Rule][]*Rule
}
func (g *RuleGraph) AddNode(n *Rule) {
g.nodes = append(g.nodes, n)
}
func (g *RuleGraph) AddEdge(n1, n2 *Rule) {
if g.edges == nil {
g.edges = make(map[Rule][]*Rule)
}
g.edges[*n1] = append(g.edges[*n1], n2)
g.edges[*n2] = append(g.edges[*n2], n1)
}
func sanitizeRule(rule string) string {
res := strings.ReplaceAll(rule, " bags", "")
res = strings.ReplaceAll(res, " bag", "")
res = strings.ReplaceAll(res, ".", "")
res = strings.TrimSpace(res)
return res
}
func parseRule(rule string, tree *RuleGraph) {
header := sanitizeRule(strings.Split(rule, "contain")[0])
content := sanitizeRule(strings.Split(rule, "contain")[1])
var node = Rule{header, -1}
tree.AddNode(&node)
for _, c := range strings.Split(content, ",") {
c = sanitizeRule(c)
quantity, _ := strconv.Atoi(string(c[0]))
c = c[2:]
node2 := Rule{c, quantity}
tree.AddNode(&node2)
tree.AddEdge(&node, &node2)
}
}
func alreadyInArray(x *[]string, element string) bool {
for _, c := range *x {
if element == c {
return true
}
}
return false
}
func navigateTree(g *RuleGraph, query string, seen *[]string) int {
count := 1
for i := 0; i < len(g.nodes); i++ {
near := g.edges[*g.nodes[i]]
for j := 0; j < len(near); j++ {
if near[j].quantity == -1 {
continue
}
if near[j].content == query {
if alreadyInArray(seen, g.nodes[i].content) {
continue
}
count = count + navigateTree(g, g.nodes[i].content, seen)
*seen = append(*seen, g.nodes[i].content)
}
}
}
return count
}
func main() {
f, _ := os.Open("input.txt")
b := bufio.NewScanner(f)
var root RuleGraph
i := 0
for b.Scan() {
line := b.Text()
parseRule(line, &root)
i++
}
seen := make([]string, 0, i)
part1 := navigateTree(&root, "shiny gold", &seen)-1
fmt.Println("Answer (part 1):", part1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment