Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Symbol extend [ value: arg [^arg perform: self] ]
- Collection extend [ min [^self fold: [:a :b | a min: b]] ]
- Interval class extend [ start: start length: len [^start to: (start + len - 1)] ]
- Interval extend [
- " Get intersection of self and another Interval "
- & other [ ^(self first max: other first) to: (self last min: other last) ]
- ]
- Interval subclass: Mapping [
- | dest |
- Mapping class >> new: str [
- | nums |
- nums := str subStrings collect: #asNumber.
- ^(super from: nums second to: nums second + nums third - 1) init: nums first.
- ]
- Mapping class >> from: arr [
- ^(super from: arr second to: arr second + arr third - 1) init: arr first.
- ]
- init: d [ dest := d. ^self ]
- dest [ ^dest ]
- ]
- "
- | Mainline
- "
- sections := (stdin contents tokenize: '\n\n') collect: #lines.
- seeds := sections first first subStrings allButFirst collect: #asNumber.
- " Get seed ranges for part 2: "
- ranges := (1 to: seeds size // 2) collect: [ :n |
- (seeds at: 2*n-1) to: (seeds at: 2*n-1) + (seeds at: 2*n) - 1
- ].
- " Read in mappings. ASSUME: sections are in order "
- map := OrderedCollection new.
- sections allButFirst do: [ :lines |
- typeMap := lines allButFirst asOrderedCollection collect: [:str | Mapping new: str].
- " Fill in missing identity maps: "
- typeMap sort: [:a :b | a first < b first].
- ident := OrderedCollection new.
- curr := 0.
- typeMap do: [ :rule |
- (rule first > curr) ifTrue: [
- ident add: (Mapping from: {curr. curr. rule first - curr}).
- ].
- curr := rule last + 1.
- ].
- (curr < (2 raisedTo: 32)) ifTrue: [
- ident add: (Mapping from: {curr. curr. (2 raisedTo: 32) - curr}).
- ].
- map add: (typeMap, ident).
- ].
- " Part 1: "
- locations := seeds collect: [:seed |
- map inject: seed into: [:loc :rules |
- | trans |
- trans := rules detect: [:r | loc between: r first and: r last].
- trans dest + (loc - trans first).
- ].
- ].
- ('Part 1: %1' % {locations min}) displayNl.
- " Part 2: "
- " For each mapping, collect the mapped sub-ranges of each range and gather together. "
- map do: [ :rules |
- ranges := ranges gather: [ :seeds |
- (rules collect: [ :rule |
- | inter |
- inter := rule & seeds.
- (inter size > 0) ifTrue: [
- Interval start: rule dest + (inter first - rule first)
- length: inter size.
- ]
- ]) select: #notNil.
- ].
- ].
- ('Part 2: %1' % {(ranges collect: #first) min}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement