Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- " Split input by sections "
- section := stdin contents tokenize: '\n\n'.
- "
- | First section: rules
- "
- rules := (section first) tokenize: '\n'.
- num_fields := rules size.
- " Make set of all valid numbers to test against "
- valid := Set new.
- f_valid := (Array new: num_fields) collect: [ :n | Set new ].
- "nums := (0 to: num_fields) collect: [:n | n]."
- rules doWithIndex:
- [ :s :i | (s =~ '(\d+)-(\d+) or (\d+)-(\d+)') ifMatched: [ :r |
- (r at: 1) asNumber to: (r at: 2) asNumber do: [ :n |
- valid add: n.
- (f_valid at: i) add: n.
- ].
- (r at: 3) asNumber to: (r at: 4) asNumber do: [ :n |
- valid add: n.
- (f_valid at: i) add: n.
- ].
- ].
- ].
- "
- | Second sections: my ticket
- "
- my_ticket := ((((section second) subStrings: Character nl) last)
- subStrings: $,) collect: [:n | n asNumber].
- "
- | Third section: other tickets
- "
- " Turn tickets into OrderedCollections of numbers "
- others := ((section third) subStrings: Character nl) removeFirst; yourself.
- others := (others collect: [:t | (t subStrings: '\n,') collect: [:n | n asNumber]]).
- " init table with everything being valid "
- f_table := (Array new: num_fields) collect: [ :n | Set withAll: (1 to: num_fields) ].
- " For valid tickets, scan to remove invalid possibilities from table "
- others do: [ :t |
- (t conform: [ :n | (valid includes: n) ]) ifTrue: [
- (1 to: num_fields) do: [ :i |
- (1 to: num_fields) do: [ :f |
- ((f_valid at: f) includes: (t at: i)) ifFalse: [
- (f_table at: i) remove: f.
- ]
- ]
- ]
- ]
- ].
- " Find the ones with only one choice, mark them in the key, delete for others, repeat "
- answer_key := LookupTable new.
- [ answer_key size < num_fields ] whileTrue: [
- (1 to: num_fields) do: [ :i |
- ((f_table at: i) size = 1) ifTrue: [
- ans := (f_table at: i) anyOne.
- answer_key at: ans put: i.
- (1 to: num_fields) do: [ :j |
- (f_table at: j) remove: ans ifAbsent: [].
- ]
- ]
- ]
- ].
- " Assuming first six rules are the destination ones "
- part2 := (1 to: 6) inject: 1 into: [ :a :i | a * (my_ticket at: (answer_key at: i)) ].
- stdout nextPutAll: ('Part 2: ', part2 asString); nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement