Skip to content

Commit 946a03b

Browse files
committed
solve 17th day 2nd task
1 parent dc7e8cf commit 946a03b

File tree

1 file changed

+51
-10
lines changed
  • year2024/src/main/kotlin/net/olegg/aoc/year2024/day17

1 file changed

+51
-10
lines changed

year2024/src/main/kotlin/net/olegg/aoc/year2024/day17/Day17.kt

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,61 @@ import java.math.BigInteger
99
*/
1010
object Day17 : DayOf2024(17) {
1111
private val numberPattern = "(-?\\d+)".toRegex()
12+
private val EIGHT = 8.toBigInteger()
13+
1214
override fun first(): Any? {
1315
val (rawRegisters, rawProgram) = data.split("\n\n")
16+
val (a, b, c) = rawRegisters.lines().mapNotNull { line ->
17+
numberPattern.find(line)?.value?.toBigInteger()
18+
}
19+
val program = numberPattern.findAll(rawProgram).map { it.value.toInt() }.toList()
1420

15-
var (a, b, c) = rawRegisters.lines()
16-
.mapNotNull { line ->
17-
numberPattern.find(line)?.value?.toBigInteger()
18-
}
21+
return calculate(program, a, b, c).joinToString(separator = ",")
22+
}
1923

24+
override fun second(): Any? {
25+
val rawProgram = data.substringAfter("\n\n")
2026
val program = numberPattern.findAll(rawProgram).map { it.value.toInt() }.toList()
2127

28+
val mapping = (0 until 4096).associate { startA ->
29+
(0..3).map { (startA shr (3 * it)) and 7 } to calculate(program, startA.toBigInteger()).first()
30+
}
31+
32+
val startConfig = mapping.filter { it.value == program.first() }
33+
.keys
34+
.groupingBy { it.drop(1) }
35+
.fold(Int.MAX_VALUE) { min, list -> minOf(min, list.first()) }
36+
.mapValues { it.value.toBigInteger() }
37+
38+
val result = program.drop(1).foldIndexed(startConfig) { index, acc, op ->
39+
val fit = mapping.filter { it.value == op }.filter { it.key.dropLast(1) in acc }
40+
41+
fit.keys
42+
.groupingBy { it.drop(1) }
43+
.fold(Int.MAX_VALUE) { min, list -> minOf(min, list.first()) }
44+
.mapValues { it.value.toBigInteger().shl((index + 1) * 3) + acc[listOf(it.value) + it.key.dropLast(1)]!! }
45+
}
46+
47+
val best = result.minOf { (rawHead, tail) ->
48+
val head = rawHead.reduceRight { value, acc -> acc * 8 + value }.toBigInteger()
49+
head.shl(3 * program.size) + tail
50+
}
51+
52+
check(calculate(program, best) == program)
53+
54+
return best
55+
}
56+
57+
private fun calculate(
58+
program: List<Int>,
59+
startA: BigInteger,
60+
startB: BigInteger = BigInteger.ZERO,
61+
startC: BigInteger = BigInteger.ZERO,
62+
): List<Int> = buildList {
63+
var a = startA
64+
var b = startB
65+
var c = startC
66+
2267
fun combo(input: Int): BigInteger = when (input) {
2368
in 0..3 -> input.toBigInteger()
2469
4 -> a
@@ -27,8 +72,6 @@ object Day17 : DayOf2024(17) {
2772
else -> error("Unexpected value")
2873
}
2974

30-
val output = mutableListOf<BigInteger>()
31-
3275
var position = 0
3376
while (position in program.indices) {
3477
val instruction = program[position++]
@@ -37,16 +80,14 @@ object Day17 : DayOf2024(17) {
3780
when (instruction) {
3881
0 -> a = a.div(BigInteger.TWO.pow(combo(operand).toInt()))
3982
1 -> b = b xor operand.toBigInteger()
40-
2 -> b = combo(operand).mod(8.toBigInteger())
83+
2 -> b = combo(operand).mod(EIGHT)
4184
3 -> position = if (a != BigInteger.ZERO) operand else position
4285
4 -> b = b xor c
43-
5 -> output += combo(operand).mod(8.toBigInteger())
86+
5 -> add(combo(operand).mod(EIGHT).toInt())
4487
6 -> b = a.div(BigInteger.TWO.pow(combo(operand).toInt()))
4588
7 -> c = a.div(BigInteger.TWO.pow(combo(operand).toInt()))
4689
}
4790
}
48-
49-
return output.joinToString(separator = ",")
5091
}
5192
}
5293

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy