Skip to content

Instantly share code, notes, and snippets.

@fxn
Created December 7, 2020 20:49
Show Gist options
  • Select an option

  • Save fxn/8bc1b1c3a8baa220b57fb0886136e7e4 to your computer and use it in GitHub Desktop.

Select an option

Save fxn/8bc1b1c3a8baa220b57fb0886136e7e4 to your computer and use it in GitHub Desktop.
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
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