package day2 import java.io.File object Day2 { fun sumOfCompatibleGames(hand: Hand) = readGames() .filter { it.isCompatibleWith(hand) } .map(Game::id) .sum() private fun readGames(): List = File("src/main/resources/day2/input.txt") .readLines() .map(Game.Companion::parse) } data class Game(val id: Int, val hands: List) { fun isCompatibleWith(hand: Hand) = hand.fitsIn( hands.fold(Hand(0, 0, 0)) { currentMax: Hand, next: Hand -> Hand( maxOf(currentMax.red, next.red), maxOf(currentMax.green, next.green), maxOf(currentMax.blue, next.blue) ) }) companion object { /** * Example string: "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green" */ fun parse(string: String) = string .split(':') .let { Game( id = NUMBER_REGEX.find(it[0])!!.value.toInt(), hands = it[1].split(';').map { Hand.parse(it) }) } private val NUMBER_REGEX = Regex("\\d") } } data class Hand(val red: Int, val green: Int, val blue: Int) { fun fitsIn(other: Hand) = red >= other.red && green >= other.green && blue >= other.blue companion object { /** * Example string: "3 blue, 4 red" */ fun parse(string: String): Hand = Hand( RED_REGEX.find(string)?.groupValues?.get(1)?.toInt() ?: 0, GREEN_REGEX.find(string)?.groupValues?.get(1)?.toInt() ?: 0, BLUE_REGEX.find(string)?.groupValues?.get(1)?.toInt() ?: 0 ) private val RED_REGEX = Regex("""(\d+)\s+red""") private val GREEN_REGEX = Regex("""(\d+)\s+green""") private val BLUE_REGEX = Regex("""(\d+)\s+blue""") } }