1
0
Files
Advent-of-Code/2020/src/main/kotlin/Day22.kt
T
2021-12-01 19:32:38 +01:00

77 lines
2.1 KiB
Kotlin

package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Groups
private data class PlayedGame(val a: List<Int>, val b: List<Int>)
@Day(22)
class Day22(@Groups val input: List<List<String>>) {
private val one = input[0].drop(1).map { it.toInt() }
private val two = input[1].drop(1).map { it.toInt() }
fun part1(): Long {
val oneDeque = ArrayDeque(one)
val twoDeque = ArrayDeque(two)
while (oneDeque.isNotEmpty() && twoDeque.isNotEmpty()) {
val a = oneDeque.removeFirst()
val b = twoDeque.removeFirst()
if (a > b) {
oneDeque.addLast(a)
oneDeque.addLast(b)
} else {
twoDeque.addLast(b)
twoDeque.addLast(a)
}
}
val deque = if (oneDeque.isEmpty()) twoDeque else oneDeque
return deque.score()
}
private fun ArrayDeque<Int>.score() =
asReversed().mapIndexed { index, value -> (index + 1).toLong() * value.toLong() }.sum()
fun part2(): Long {
val oneDeque = ArrayDeque(one)
val twoDeque = ArrayDeque(two)
val winner = playGame(oneDeque, twoDeque)
val deque = if (winner == 1) oneDeque else twoDeque
return deque.score()
}
private fun playGame(one: ArrayDeque<Int>, two: ArrayDeque<Int>): Int {
val playedGames = mutableSetOf<PlayedGame>()
while (one.isNotEmpty() && two.isNotEmpty()) {
if (!playedGames.add(PlayedGame(one.toList(), two.toList()))) return 1
val a = one.removeFirst()
val b = two.removeFirst()
val winner = when {
one.size >= a && two.size >= b -> playGame(
ArrayDeque(one.take(a)),
ArrayDeque(two.take(b))
)
a > b -> 1
else -> 2
}
if (winner == 1) {
one.addLast(a)
one.addLast(b)
} else {
two.addLast(b)
two.addLast(a)
}
}
return if (one.isEmpty()) 2 else 1
}
}