Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- " Helper function so we can split with a string, not just a character "
- String extend [
- splitString: str [
- | ret rs |
- ret := OrderedCollection new.
- rs := self readStream.
- [ rs atEnd ] whileFalse: [ ret addLast: (rs upToAll: str) ].
- ^ret
- ]
- ]
- "
- | Subclassing Dictionary to make one with the recursive functions we need.
- "
- Dictionary subclass: RulesDictionary [
- <shape: #pointer>
- " Recursive method for part 1 "
- hasGold: bag [
- | kids idx |
- kids := self at: bag.
- kids detect: [ :child | (child second = 'shiny gold')
- or: [self hasGold: child second] ]
- ifNone: [ ^false ].
- ^true
- ]
- " Recursive method for part 2 "
- countBags: bag [
- ^(self at: bag) inject: 1 into: [ :a :b |
- a + (b first asNumber * (self countBags: b second))
- ]
- ]
- ]
- "
- | Mainline
- "
- rules := RulesDictionary new.
- " Parse rules "
- stdin linesDo: [ :line|
- rule := line splitString: ' bags contain '.
- container := rule first.
- contents := ((rule second substrings: $,)
- reject: [ :b | (b =~ 'no other') matched ])
- collect: [ :b | (b =~ '(\d+) (.*?) bag') asArray ].
- rules at: container put: contents.
- ].
- " Get bags that ultimately contain a shiny gold one "
- gold_bags := (rules keys) select: [ :bag | rules hasGold: bag ].
- stdout nextPutAll: 'Part 1: ', gold_bags size asString; nl.
- " Get minimum number of bags that must be in a shiny gold one "
- stdout nextPutAll: 'Part 2: ', ((rules countBags: 'shiny gold') - 1) asString; nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement