Advertisement
musifter

AoC 2021 day 12 (smalltalk)

Dec 12th, 2021
1,939
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. Bag extend [
  4.     " #copyWith: on Bag doesn't create a new object, making version that does "
  5.     deepCopyWith: item [ ^self deepCopy add: item; yourself ]
  6. ]
  7.  
  8. Dictionary subclass: CaveGraph [
  9.     <shape: #pointer>
  10.     | big validBlock |
  11.     CaveGraph class >> from: linkArray [
  12.         ^super new init: linkArray
  13.     ]
  14.  
  15.     init: linkArray [
  16.         linkArray do: [ :link |
  17.             (self at: link key ifAbsentPut: [Set new]) add: link value.
  18.             (self at: link value ifAbsentPut: [Set new]) add: link key.
  19.         ].
  20.  
  21.         " No return to #start, so make those links directional "
  22.         self do: [:set | set remove: #start ifAbsent: []].
  23.  
  24.         big := self keys select: [:sym | (sym asString at: 1) isUppercase].
  25.         ^self
  26.     ]
  27.  
  28.     recursePath: node visited: vis [
  29.         (node = #end) ifTrue: [ ^1 ].
  30.  
  31.         " select valid neighbours, then recurse them and sum results "
  32.         ^((self at: node) select: [ :node |
  33.             ((big includes: node) or: [validBlock value: node value: vis])
  34.  
  35.         ]) inject: 0 into: [:acc :neigh |
  36.             acc + (self recursePath: neigh visited: ((big includes: neigh)
  37.                                                     ifTrue:  [vis]
  38.                                                     ifFalse: [vis deepCopyWith: neigh]))
  39.         ]
  40.     ]
  41.  
  42.     countValid: rule [
  43.         " count paths from #start to #end, applying rule to validate moves to small caves "
  44.         validBlock := rule.
  45.         ^self recursePath: #start visited: Bag new.
  46.     ]
  47. ]
  48.  
  49. "
  50. | Mainline
  51. "
  52. graph := CaveGraph from: (stdin lines contents collect: [:line |
  53.              ends := line substrings: $-.
  54.              ends first asSymbol -> ends second asSymbol
  55.          ]).
  56.  
  57. graph inspect.
  58.  
  59. 'Part 1: ' display.
  60. (graph countValid: [:n :vis | (vis includes: n) not]) displayNl.
  61.  
  62. 'Part 2: ' display.
  63. (graph countValid: [:n :vis |
  64.     (vis includes: n) not or: [vis sortedByCount first key < 2]
  65. ]) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement