diff --git a/2020/src/day7.nim b/2020/src/day7.nim new file mode 100644 index 0000000..ed8f139 --- /dev/null +++ b/2020/src/day7.nim @@ -0,0 +1,51 @@ +import streams, sequtils, pegs, tables, sets, algorithm, strutils + +let parser = peg""" +grammar <- c ' bags contain ' (nc+ / nob) '.' +nob <- 'no other bags' +nc <- {\d} ' ' c ' bag' 's'? ', '? +c <- {\ident ' ' \ident} +""" + +iterator asParsed(s: Stream): (string, seq[string]) = + for l in s.lines: + if l =~ parser: + var d = matches.filterIt(it != "").reversed + let key = d.pop + yield (key, d) + +proc walkUp(t: TableRef[string, HashSet[string]], tar: string): HashSet[string] = + if t.contains(tar): + let parents = t[tar] + echo parents + result = parents + for p in parents: + echo p + result = result + t.walkUp(p) + +proc part1*(s: Stream): int = + var t = newTable[string, HashSet[string]]() + for (key, parsed) in s.asParsed: + var parents = parsed.filterIt(not(it =~ peg"\d+")) + for p in parents: + if t.contains(p): t[p].incl(key) + else: t[p] = [key].toHashSet() + t.walkUp("shiny gold").len + +proc walkDown(t: TableRef[string, TableRef[string, int]], tar: string): int = + let children = t[tar] + for (s, n) in children.pairs: + result += n + (n * t.walkDown(s)) + +iterator asPairChunks(s: seq[string]): (string, int) = + for i in countup(0, s.len - 1, 2): yield (s[i], s[i+1].parseInt) + +proc part2*(s: Stream): int = + var t = newTable[string, TableRef[string, int]]() + for (key, parsed) in s.asParsed: + echo key, parsed + var innert = newTable[string, int]() + for (innerkey, n) in parsed.asPairChunks: + innert[innerkey] = n + t[key] = innert + t.walkDown "shiny gold"