Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Bag extend [
- " #copyWith: on Bag doesn't create a new object, making version that does "
- deepCopyWith: item [ ^self deepCopy add: item; yourself ]
- ]
- Dictionary subclass: CaveGraph [
- <shape: #pointer>
- | big validBlock |
- CaveGraph class >> from: linkArray [
- ^super new init: linkArray
- ]
- init: linkArray [
- linkArray do: [ :link |
- (self at: link key ifAbsentPut: [Set new]) add: link value.
- (self at: link value ifAbsentPut: [Set new]) add: link key.
- ].
- " No return to #start, so make those links directional "
- self do: [:set | set remove: #start ifAbsent: []].
- big := self keys select: [:sym | (sym asString at: 1) isUppercase].
- ^self
- ]
- recursePath: node visited: vis [
- (node = #end) ifTrue: [ ^1 ].
- " select valid neighbours, then recurse them and sum results "
- ^((self at: node) select: [ :node |
- ((big includes: node) or: [validBlock value: node value: vis])
- ]) inject: 0 into: [:acc :neigh |
- acc + (self recursePath: neigh visited: ((big includes: neigh)
- ifTrue: [vis]
- ifFalse: [vis deepCopyWith: neigh]))
- ]
- ]
- countValid: rule [
- " count paths from #start to #end, applying rule to validate moves to small caves "
- validBlock := rule.
- ^self recursePath: #start visited: Bag new.
- ]
- ]
- "
- | Mainline
- "
- graph := CaveGraph from: (stdin lines contents collect: [:line |
- ends := line substrings: $-.
- ends first asSymbol -> ends second asSymbol
- ]).
- graph inspect.
- 'Part 1: ' display.
- (graph countValid: [:n :vis | (vis includes: n) not]) displayNl.
- 'Part 2: ' display.
- (graph countValid: [:n :vis |
- (vis includes: n) not or: [vis sortedByCount first key < 2]
- ]) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement