Created
December 7, 2020 20:49
-
-
Save fxn/8bc1b1c3a8baa220b57fb0886136e7e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import re, strutils, sequtils, tables, sets | |
| type | |
| ContainedBag = tuple | |
| number: int | |
| color: string | |
| Rule = tuple | |
| color: string | |
| contains: seq[ContainedBag] | |
| func parseRule(line: string): Rule = | |
| var rest: string | |
| if line =~ re"^(.*?) bags contain (.*)\.$": | |
| result.color = matches[0] | |
| rest = matches[1] | |
| if rest != "no other bags": | |
| for contained in rest.split(", "): | |
| if contained =~ re"^(\d+)\s+(.*) bags?$": | |
| let containedBag = (matches[0].parseInt, matches[1]) | |
| result.contains.add(containedBag) | |
| func initContainedIn(rules: seq[Rule]): Table[string, seq[string]] = | |
| for rule in rules: | |
| for contained in rule.contains: | |
| if not result.hasKey(contained.color): | |
| result[contained.color] = @[] | |
| result[contained.color].add(rule.color) | |
| var rules = toSeq(stdin.lines).map(parseRule) | |
| var containedIn = initContainedIn(rules) | |
| var canContain: HashSet[string] | |
| var toVisit = containedIn["shiny gold"] | |
| while toVisit.len != 0: | |
| let color = toVisit.pop | |
| canContain.incl(color) | |
| if containedIn.hasKey(color): | |
| for parent in containedIn[color]: | |
| if not canContain.contains(parent): | |
| toVisit.add(parent) | |
| echo canContain.card |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import re, strutils, sequtils, tables | |
| type | |
| ContainedBag = tuple | |
| number: int | |
| color: string | |
| Rule = tuple | |
| color: string | |
| contains: seq[ContainedBag] | |
| func parseRule(line: string): Rule = | |
| var rest: string | |
| if line =~ re"^(.*?) bags contain (.*)\.$": | |
| result.color = matches[0] | |
| rest = matches[1] | |
| if rest != "no other bags": | |
| for contained in rest.split(", "): | |
| if contained =~ re"^(\d+)\s+(.*) bags?$": | |
| let containedBag = (matches[0].parseInt, matches[1]) | |
| result.contains.add(containedBag) | |
| func count(contains: TableRef[string, seq[ContainedBag]], color: string): int = | |
| result = 1 | |
| for containedBag in contains[color]: | |
| result += containedBag.number*count(contains, containedBag.color) | |
| var rules = toSeq(stdin.lines).map(parseRule) | |
| var contains = newTable[string, seq[ContainedBag]]() | |
| for rule in rules: | |
| contains[rule.color] = rule.contains | |
| echo count(contains, "shiny gold") - 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment