musifter

AoC 2021 day 7 (Smalltalk)

Dec 7th, 2021
889
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. Collection extend [
  4.     apply: method  [ ^self collect: [:x | x perform: method] ]
  5.     sum            [ ^self fold: [:a :b | a + b] ]
  6.  
  7.     " Calculate total fuel to get to val, using weight block "
  8.     getFuel: val weight: block [
  9.         ^self inject: 0 into: [ :acc :x |
  10.             acc + (block value: val value: x)
  11.         ]
  12.     ]
  13. ]
  14.  
  15. Integer extend [
  16.     " Extension to calculate triangular numbers "
  17.     triangle  [ ^(self * (self + 1)) / 2 ]
  18. ]
  19.  
  20. "
  21. | Mainline
  22. "
  23. input := ((stdin nextLine substrings: $,) apply: #asNumber) sorted.
  24.  
  25. " Part 1 is at median.  If list is even it has two medians, but all values
  26. | between them will give the same result by symmetry as moving from one to
  27. | the other involves adding fuel for half on one side and subtracting the
  28. | same amount from the other half. "
  29. median := input at: input size // 2.
  30. part1  := input getFuel: median weight: [:x :y | (x - y) abs].
  31.  
  32. ('Part 1: %1' % {part1}) displayNl.
  33.  
  34. " Part 2 is around the mean.  The mean is almost certainly not an integer,
  35. | which is what we want.  So take the minimum of the integers on either side of it. "
  36. mean  := input sum // input size.
  37. part2 := {mean. mean + 1} inject: SmallInteger largest into: [ :acc :mean |
  38.              acc min: (input getFuel: mean weight: [:x :y | (x - y) abs triangle])
  39.          ].
  40.  
  41. ('Part 2: %1' % {part2}) displayNl.
  42.  
RAW Paste Data