Advertisement
musifter

AoC day 21, Smalltalk

Dec 21st, 2020
2,216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. LookupTable extend [
  4.     incAt: key [
  5.         ^self at: key put: (self at: key ifAbsent: [0]) + 1.
  6.     ]
  7. ]
  8.  
  9. String extend [
  10.     splitString: str [
  11.         | ret rs |
  12.         ret := OrderedCollection new.
  13.         rs  := self readStream.
  14.         [ rs atEnd ] whileFalse: [ ret addLast: (rs upToAll: str) ].
  15.         ^ret
  16.     ]
  17. ]
  18.  
  19. Object subclass: Allergen [
  20.     | name num_rule poss_ing |
  21.  
  22.     Allergen class >> add: a_name [
  23.         ^(super new) init: a_name.
  24.     ]
  25.  
  26.     init: a_name [
  27.         name     := a_name.
  28.         num_rule := 0.
  29.         poss_ing := LookupTable new.
  30.         ^self
  31.     ]
  32.  
  33.     incRule [
  34.         num_rule := num_rule + 1.
  35.         ^self
  36.     ]
  37.  
  38.     addPossible: ingArray [
  39.         ingArray do: [ :i | poss_ing incAt: i ].
  40.         ^self
  41.     ]
  42.  
  43.     reducePossible [
  44.         ^poss_ing := poss_ing select: [ :n | n = num_rule ].
  45.     ]
  46.  
  47.     getPossible [
  48.         ^poss_ing
  49.     ]
  50.  
  51.     removePossible: ing [
  52.         ^poss_ing removeKey: ing ifAbsent: [].
  53.     ]
  54. ]
  55.  
  56. "
  57. |  Mainline
  58. "
  59. ingreds   := LookupTable new.
  60. allergens := LookupTable new.
  61.  
  62. stdin linesDo: [ :line |
  63.     parts := line splitString: '(contains '.
  64.  
  65.     rule_ing := (parts first substrings).
  66.     rule_ing do: [ :i | ingreds incAt: i ].
  67.  
  68.     (parts second subStrings: ', )') do: [ :rule_all |
  69.         (allergens at: rule_all ifAbsentPut: [ Allergen add: rule_all ])
  70.                    incRule; addPossible: rule_ing.
  71.     ].
  72. ].
  73.  
  74. poss := Set new.
  75. allergens do: [ :a | poss addAll: a reducePossible keys ].
  76.  
  77. " Assuming reducePossible leaves just the allergens (works for input)"
  78. 'Part 1: ' display.
  79. ((ingreds keys - poss) inject: 0 into: [:a :b | a + (ingreds at: b)]) displayNl.
  80.  
  81. " Part 2 "
  82. allerg := allergens keys.
  83. ans_key := LookupTable new.
  84. [ allerg size > 0 ] whileTrue: [
  85.     allerg do: [ :a |
  86.         ings := (allergens at: a) getPossible.
  87.         (ings size == 1) ifTrue: [
  88.             i := ings keys anyOne.
  89.             ans_key at: a put: i.
  90.             poss remove: i.
  91.             allerg remove: a.
  92.             allerg do: [ :j | (allergens at: j) removePossible: i ].
  93.         ]
  94.     ]
  95. ].
  96.  
  97. 'Part 2: ' display.
  98. part2 := OrderedCollection new.
  99. allergens keys sorted do: [ :a | part2 add: (ans_key at: a) ].
  100. (String join: part2 separatedBy: ',') displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement