|
1 | 1 | package AdventOfCode2022
|
2 | 2 |
|
3 | 3 | object Day20:
|
4 | | - case class Node(value: Long, var prev: Node, var next: Node) |
5 | | - |
6 | | - def parse(input: Seq[Int], key: Long): Seq[Node] = |
7 | | - val nodes = input.map(n => Node(n * key, null, null)) |
8 | | - nodes.zipWithIndex.foreach { (node, i) => |
9 | | - node.prev = nodes((i - 1 + nodes.size) % nodes.size) |
10 | | - node.next = nodes((i + 1) % nodes.size) |
11 | | - } |
12 | | - nodes |
13 | | - |
14 | | - def mix(nodes: Seq[Node]): Unit = |
15 | | - for node <- nodes do |
16 | | - val remainder = (node.value % (nodes.size - 1)).toInt |
17 | | - val move = if remainder >= 0 then remainder else remainder + nodes.size - 1 |
18 | | - for _ <- 1 to move do |
19 | | - val (a, b, c, d) = (node.prev, node, node.next, node.next.next) |
20 | | - a.next = c |
21 | | - b.prev = c |
22 | | - b.next = d |
23 | | - c.prev = a |
24 | | - c.next = b |
25 | | - d.prev = b |
| 4 | + def decrypt(input: Seq[Int], key: Long, rounds: Int): Long = |
| 5 | + val mixed = collection.mutable.ArrayBuffer.from(input.map(_ * key).zipWithIndex) |
| 6 | + for _ <- 1 to rounds do |
| 7 | + for index <- input.indices do |
| 8 | + val from = mixed.indexWhere(_._2 == index) |
| 9 | + val pair @ (number, _) = mixed.remove(from) |
| 10 | + val remainder = (number % mixed.size).toInt |
| 11 | + val to = (from + remainder + mixed.size) % mixed.size |
| 12 | + mixed.insert(to, pair) |
26 | 13 | end for
|
27 | 14 | end for
|
| 15 | + val start = mixed.indexWhere(_._1 == 0) |
| 16 | + (1 to 3).map(offset => mixed((start + 1000 * offset) % mixed.size)._1).sum |
28 | 17 |
|
29 | | - def skip(start: Node): Node = Iterator.iterate(start)(_.next).drop(1000).next() |
30 | | - |
31 | | - def decrypt(input: Seq[Int], key: Long, rounds: Int): Long = |
32 | | - val nodes = parse(input, key) |
33 | | - for _ <- 1 to rounds do mix(nodes) |
34 | | - val start = nodes.find(_.value == 0).get |
35 | | - Iterator.iterate(start)(skip).drop(1).take(3).map(_.value).sum |
36 | | - |
37 | | - def part1(input: Seq[Int]): Long = decrypt(input, 1, 1) |
| 18 | + def part1(input: Seq[Int]): Long = decrypt(input, 1L, 1) |
38 | 19 |
|
39 | 20 | def part2(input: Seq[Int]): Long = decrypt(input, 811589153L, 10)
|
40 | 21 |
|
|
0 commit comments