Advertisement
musifter

AoC 2023, day 5, both parts (Smalltalk)

Dec 5th, 2023
1,741
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 2.73 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Symbol extend     [ value: arg  [^arg perform: self]             ]
  4. Collection extend [ min         [^self fold: [:a :b | a min: b]] ]
  5.  
  6. Interval class extend [ start: start length: len [^start to: (start + len - 1)] ]
  7.  
  8. Interval extend [
  9.     " Get intersection of self and another Interval "
  10.     & other [ ^(self first max: other first) to: (self last min: other last) ]
  11. ]
  12.  
  13. Interval subclass: Mapping [
  14.     | dest |
  15.     Mapping class >> new: str [
  16.         | nums |
  17.         nums := str subStrings collect: #asNumber.
  18.         ^(super from: nums second to: nums second + nums third - 1) init: nums first.
  19.     ]
  20.  
  21.     Mapping class >> from: arr [
  22.         ^(super from: arr second to: arr second + arr third - 1) init: arr first.
  23.     ]
  24.  
  25.     init: d [ dest := d.  ^self ]
  26.     dest    [ ^dest ]
  27. ]
  28.  
  29. "
  30. | Mainline
  31. "
  32. sections := (stdin contents tokenize: '\n\n') collect: #lines.
  33.  
  34. seeds  := sections first first subStrings allButFirst collect: #asNumber.
  35.  
  36. " Get seed ranges for part 2: "
  37. ranges := (1 to: seeds size // 2) collect: [ :n |
  38.               (seeds at: 2*n-1) to: (seeds at: 2*n-1) + (seeds at: 2*n) - 1
  39.           ].
  40.  
  41. " Read in mappings.  ASSUME: sections are in order "
  42. map := OrderedCollection new.
  43. sections allButFirst do: [ :lines |
  44.     typeMap := lines allButFirst asOrderedCollection collect: [:str | Mapping new: str].
  45.  
  46.     " Fill in missing identity maps: "
  47.     typeMap sort: [:a :b | a first < b first].
  48.  
  49.     ident := OrderedCollection new.
  50.     curr := 0.
  51.     typeMap do: [ :rule |
  52.         (rule first > curr) ifTrue: [
  53.             ident add: (Mapping from: {curr. curr. rule first - curr}).
  54.         ].
  55.         curr := rule last + 1.
  56.     ].
  57.  
  58.     (curr < (2 raisedTo: 32)) ifTrue: [
  59.         ident add: (Mapping from: {curr. curr. (2 raisedTo: 32) - curr}).
  60.     ].
  61.  
  62.     map add: (typeMap, ident).
  63. ].
  64.  
  65. " Part 1: "
  66. locations := seeds collect: [:seed |
  67.                  map inject: seed into: [:loc :rules |
  68.                     | trans |
  69.                      trans := rules detect: [:r | loc between: r first and: r last].
  70.                      trans dest + (loc - trans first).
  71.                  ].
  72.              ].
  73.  
  74. ('Part 1: %1' % {locations min}) displayNl.
  75.  
  76. " Part 2: "
  77. " For each mapping, collect the mapped sub-ranges of each range and gather together. "
  78. map do: [ :rules |
  79.     ranges := ranges gather: [ :seeds |
  80.         (rules collect: [ :rule |
  81.            | inter |
  82.             inter := rule & seeds.
  83.             (inter size > 0) ifTrue: [
  84.                 Interval start:  rule dest + (inter first - rule first)
  85.                          length: inter size.
  86.             ]
  87.         ]) select: #notNil.
  88.     ].
  89. ].
  90.  
  91. ('Part 2: %1' % {(ranges collect: #first) min}) displayNl.
  92.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement