Advertisement
Guest User

AoC day 7, Smalltalk

a guest
Dec 7th, 2020
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. " Helper function so we can split with a string, not just a character "
  4. String extend [
  5.     splitString: str [
  6.         | ret rs |
  7.         ret := OrderedCollection new.
  8.  
  9.         rs := self readStream.
  10.         [ rs atEnd ] whileFalse: [ ret addLast: (rs upToAll: str) ].
  11.         ^ret
  12.     ]
  13. ]
  14.  
  15. "
  16. |  Subclassing Dictionary to make one with the recursive functions we need.
  17. "
  18. Dictionary subclass: RulesDictionary [
  19.     <shape: #pointer>
  20.  
  21.     " Recursive method for part 1 "
  22.     hasGold: bag [
  23.         | kids idx |
  24.         kids := self at: bag.
  25.         kids detect: [ :child | (child second = 'shiny gold')
  26.                                 or: [self hasGold: child second] ]
  27.              ifNone: [ ^false ].
  28.  
  29.         ^true
  30.     ]
  31.  
  32.     " Recursive method for part 2 "
  33.     countBags: bag [
  34.         ^(self at: bag) inject: 1 into: [ :a :b |
  35.             a + (b first asNumber * (self countBags: b second))
  36.         ]
  37.     ]
  38. ]
  39.  
  40.  
  41. "
  42. |  Mainline
  43. "
  44. rules := RulesDictionary new.
  45.  
  46. " Parse rules "
  47. stdin linesDo: [ :line|
  48.     rule := line splitString: ' bags contain '.
  49.  
  50.     container := rule first.
  51.     contents  := ((rule second substrings: $,)
  52.                     reject:  [ :b | (b =~ 'no other') matched ])
  53.                     collect: [ :b | (b =~ '(\d+) (.*?) bag') asArray ].
  54.  
  55.     rules at: container put: contents.
  56. ].
  57.  
  58. " Get bags that ultimately contain a shiny gold one "
  59. gold_bags := (rules keys) select: [ :bag | rules hasGold: bag ].
  60. stdout nextPutAll: 'Part 1: ', gold_bags size asString; nl.
  61.  
  62. " Get minimum number of bags that must be in a shiny gold one "
  63. stdout nextPutAll: 'Part 2: ', ((rules countBags: 'shiny gold') - 1) asString; nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement