Advertisement
musifter

AoC day 16 (pt2), Smalltalk

Dec 16th, 2020
2,660
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. " Split input by sections "
  4. section := stdin contents tokenize: '\n\n'.
  5.  
  6. "
  7. |  First section: rules
  8. "
  9. rules := (section first) tokenize: '\n'.
  10. num_fields := rules size.
  11.  
  12. " Make set of all valid numbers to test against "
  13. valid   := Set new.
  14. f_valid := (Array new: num_fields) collect: [ :n | Set new ].
  15. "nums := (0 to: num_fields) collect: [:n | n]."
  16.  
  17. rules doWithIndex:
  18.     [ :s :i | (s =~ '(\d+)-(\d+) or (\d+)-(\d+)') ifMatched: [ :r |
  19.             (r at: 1) asNumber to: (r at: 2) asNumber do: [ :n |
  20.                 valid add: n.
  21.                 (f_valid at: i) add: n.
  22.             ].
  23.  
  24.             (r at: 3) asNumber to: (r at: 4) asNumber do: [ :n |
  25.                 valid add: n.
  26.                 (f_valid at: i) add: n.
  27.             ].
  28.         ].
  29.     ].
  30.  
  31. "
  32. |  Second sections: my ticket
  33. "
  34. my_ticket := ((((section second) subStrings: Character nl) last)
  35.                                  subStrings: $,) collect: [:n | n asNumber].
  36.  
  37. "
  38. |  Third section: other tickets
  39. "
  40. " Turn tickets into OrderedCollections of numbers "
  41. others := ((section third) subStrings: Character nl) removeFirst; yourself.
  42. others := (others collect: [:t | (t subStrings: '\n,') collect: [:n | n asNumber]]).
  43.  
  44. " init table with everything being valid "
  45. f_table := (Array new: num_fields) collect: [ :n | Set withAll: (1 to: num_fields) ].
  46.  
  47. " For valid tickets, scan to remove invalid possibilities from table "
  48. others do: [ :t |
  49.     (t conform: [ :n | (valid includes: n) ]) ifTrue: [
  50.         (1 to: num_fields) do: [ :i |
  51.             (1 to: num_fields) do: [ :f |
  52.                 ((f_valid at: f) includes: (t at: i)) ifFalse: [
  53.                     (f_table at: i) remove: f.
  54.                 ]
  55.             ]
  56.         ]
  57.     ]
  58. ].
  59.  
  60. " Find the ones with only one choice, mark them in the key, delete for others, repeat "
  61. answer_key := LookupTable new.
  62. [ answer_key size < num_fields ] whileTrue: [
  63.     (1 to: num_fields) do: [ :i |
  64.         ((f_table at: i) size = 1) ifTrue: [
  65.             ans := (f_table at: i) anyOne.
  66.             answer_key at: ans put: i.
  67.             (1 to: num_fields) do: [ :j |
  68.                 (f_table at: j) remove: ans ifAbsent: [].
  69.             ]
  70.         ]
  71.     ]
  72. ].
  73.  
  74. " Assuming first six rules are the destination ones "
  75. part2 := (1 to: 6) inject: 1 into: [ :a :i | a * (my_ticket at: (answer_key at: i)) ].
  76. stdout nextPutAll: ('Part 2: ', part2 asString); nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement