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 [ product [^self inject: 1 into: [:a :b | a * b]] ]
- SequenceableCollection extend [
- " Return list of all pairs of elements in list "
- pairs [
- | res |
- res := OrderedCollection new.
- self allButFirst keysAndValuesDo: [:i :elem1 |
- res addAll: ((self first: i) collect: [:elem2 | {elem2. elem1}]).
- ].
- ^res
- ]
- ]
- " Structure class to calculate and store Connection data "
- Object subclass: Connection [
- | ends dist |
- Connection class >> new: endCoords [ ^super new init: endCoords ]
- init: pts [
- ends := pts.
- dist := (pts first first - pts second first) squared
- + (pts first second - pts second second) squared
- + (pts first third - pts second third) squared.
- ^self
- ]
- <= other [ ^dist <= other dist ]
- ends [ ^ends ]
- dist [ ^dist ]
- printOn: aStream [ aStream nextPutAll: dist asString ]
- ]
- "
- | Mainline
- "
- input := stdin lines contents collect: [:line | (line subStrings: $,) collect: #asNumber].
- partOneSize := (input size == 1000) ifTrue: [1000] ifFalse: [10].
- " Build SortedCollection of Connections sorted by distance "
- distTable := SortedCollection sortBlock: [:a :b | b <= a].
- input pairs do: [:pair | distTable add: (Connection new: pair)].
- " Build initial circuit graphs and backLookup vertex to graph table "
- circuits := input collect: [:pt | Set with: pt].
- backLookup := LookupTable from: (circuits gather: [:graph | graph collect: [:pt | pt -> graph]]).
- count := 0.
- [part2 isNil] whileTrue: [
- | conx graphs |
- conx := distTable removeLast.
- graphs := conx ends collect: [:end | backLookup at: end].
- (graphs first ~~ graphs second) ifTrue: [
- " Merge smaller graph into larger: "
- (graphs second size > graphs first size) ifTrue: [graphs swap: 1 with: 2].
- graphs first addAll: graphs second.
- graphs second do: [:pt | backLookup at: pt put: graphs first]; empty.
- (graphs first size == input size) ifTrue: [
- part2 := (conx ends collect: #first) product.
- ('Part 2: %1' % {part2}) displayNl.
- ]
- ].
- ((count := count + 1) == partOneSize) ifTrue: [
- part1 := ((circuits collect: #size) sorted last: 3) product.
- ('Part 1: %1' % {part1}) displayNl.
- ]
- ]
Advertisement
Add Comment
Please, Sign In to add comment