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<Game> =
|
|
File("src/main/resources/day2/input.txt")
|
|
.readLines()
|
|
.map(Game.Companion::parse)
|
|
|
|
}
|
|
|
|
data class Game(val id: Int, val hands: List<Hand>) {
|
|
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""")
|
|
}
|
|
}
|