 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