Skip to content

Commit 302917e

Browse files
authored
add day 22 code? (#793)
1 parent 4fc4c42 commit 302917e

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

2024/src/day22.scala

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package day22
2+
3+
import locations.Directory.currentDir
4+
import inputs.Input.loadFileSync
5+
6+
@main def part1: Unit =
7+
println(s"The solution is ${part1(loadInput())}")
8+
9+
@main def part2: Unit =
10+
println(s"The solution is ${part2(loadInput())}")
11+
12+
def loadInput(): String = loadFileSync(s"$currentDir/../input/day22")
13+
14+
def part1(input: String): Long =
15+
input.linesIterator.foldMap: line =>
16+
line.toLong.secretsIterator.nth(2000)
17+
18+
def part2(input: String): Long =
19+
val deltaTotals = input.linesIterator.foldMap: line =>
20+
monkeyMap(line)
21+
deltaTotals.values.max
22+
23+
def monkeyMap(line: String): Map[(Long, Long, Long, Long), Long] =
24+
given Semigroup[Long] = leftBiasedSemigroup
25+
line.toLong.secretsIterator.map(_ % 10).take(2000).sliding(5).foldMap: quintuple =>
26+
Map(deltaQuartuple(quintuple) -> quintuple(4))
27+
28+
def deltaQuartuple(q: Seq[Long]): (Long, Long, Long, Long) =
29+
(q(1) - q(0), q(2) - q(1), q(3) - q(2), q(4) - q(3))
30+
31+
extension (self: Long)
32+
private inline def step(f: Long => Long): Long = mix(f(self)).prune
33+
private inline def mix(n: Long): Long = self ^ n
34+
private inline def prune: Long = self % 16777216
35+
private inline def nextSecret: Long = step(_ * 64).step(_ / 32).step(_ * 2048)
36+
37+
def secretsIterator: Iterator[Long] =
38+
Iterator.iterate(self)(_.nextSecret)
39+
40+
trait Semigroup[A]:
41+
def combine(a0: A, a1: A): A
42+
43+
trait Monoid[A] extends Semigroup[A]:
44+
def zero: A
45+
46+
given NumericMonoid[A](using N: Numeric[A]): Monoid[A] with
47+
def zero: A = N.zero
48+
def combine(a0: A, a1: A): A = N.plus(a0, a1)
49+
50+
given MapMonoid[A, B](using S: Semigroup[B]): Monoid[Map[A, B]] with
51+
def zero: Map[A, B] = Map.empty
52+
53+
def combine(ab0: Map[A, B], ab1: Map[A, B]): Map[A, B] =
54+
ab1.foldLeft(ab0):
55+
case (ab, (a1, b1)) =>
56+
ab.updatedWith(a1):
57+
case Some(b0) => Some(S.combine(b0, b1))
58+
case None => Some(b1)
59+
60+
def leftBiasedSemigroup[A]: Semigroup[A] = (a0: A, _: A) => a0
61+
62+
extension [A](self: Iterator[A])
63+
def nth(n: Int): A =
64+
self.drop(n).next()
65+
66+
def foldMap[B](f: A => B)(using M: Monoid[B]): B =
67+
self.map(f).foldLeft(M.zero)(M.combine)

0 commit comments

Comments
 (0)