89 lines
2.8 KiB
Kotlin
89 lines
2.8 KiB
Kotlin
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)
|
|
}
|
|
}
|
|
}
|