import java.io.File typealias Round = List typealias Pull = Pair 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) { 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 { 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) } } }