adventofcode-2023/day2/day2.kt

89 lines
2.8 KiB
Kotlin
Raw Permalink Normal View History

2023-12-04 17:30:36 +00:00
import java.io.File
typealias Round = List<Pull>
typealias Pull = Pair<Color, Int>
enum class Color {
RED,
GREEN,
BLUE
}
fun main() {
val input = File("input")
val games = input.useLines { it.map { Game.fromLine(it) }.toList() }
println(games.filter { it.isValid() }.map { it.id }.sum())
println(
games
.map {
val min = it.minimumCubes()
min.first.second * min.second.second * min.third.second
}
.sum()
)
}
data class Game(val id: Int, val rounds: List<Round>) {
fun isValid(): Boolean {
return this.rounds.all {
it.all {
when (it.first) {
Color.RED -> it.second <= 12
Color.GREEN -> it.second <= 13
Color.BLUE -> it.second <= 14
}
}
}
}
fun minimumCubes(): Triple<Pull, Pull, Pull> {
return this.rounds.fold(
Triple(Pair(Color.RED, 0), Pair(Color.GREEN, 0), Pair(Color.BLUE, 0))
) { acc, next ->
next.fold(acc) { mins, pull ->
when {
pull.first == Color.RED && mins.first.second < pull.second ->
Triple(pull, mins.second, mins.third)
pull.first == Color.GREEN && mins.second.second < pull.second ->
Triple(mins.first, pull, mins.third)
pull.first == Color.BLUE && mins.third.second < pull.second ->
Triple(mins.first, mins.second, pull)
else -> mins
}
}
}
}
companion object {
fun fromLine(line: String): Game {
val (name, game) = line.split(": ")
val id = name.split(" ")[1].toInt()
val rounds =
game.split("; ").map {
it.split(", ").map {
val pull = it.split(" ")
val color =
when (pull.last()) {
"red" -> Color.RED
"green" -> Color.GREEN
"blue" -> Color.BLUE
else ->
throw Exception(
"Invalid ball color: ${pull.last()}"
)
}
val number = pull.first().toInt()
Pair(color, number)
}
}
return Game(id, rounds)
}
}
}