//> using dep org.scala-lang.modules::scala-parser-combinators::2.3.0 import aoc._ import scala.util.parsing.combinator._ case class Hand(red: Int, green: Int, blue: Int): def max(other: Hand) = Hand(red max other.red, green max other.green, blue max other.blue) def power = red * green * blue case class Game(id: Int, hands: List[Hand]): def power = hands.foldLeft(Hand(0, 0, 0))(_ max _).power object Parser extends RegexParsers: val num = """(0|[1-9]\d*)""".r ^^ { _.toInt } val update = num ~ """(red|green|blue)""".r ^^ { case (num ~ color) => color match case "red" => (h: Hand) => h.copy(red = num) case "green" => (h: Hand) => h.copy(green = num) case "blue" => (h: Hand) => h.copy(blue = num) } val hand = rep1sep(update, ",").map(_.foldRight(Hand(0, 0, 0))(_(_))) val game = "Game" ~ num ~ ":" ~ repsep(hand, ";") ^^ { case (_ ~ num ~ _ ~ hands) => Game(num, hands) } end Parser // Part 1 def getGames = lines.map(Parser.parse(Parser.game, _).get) def part1 = val games = getGames.toList val res = games .filter(g => g.hands.forall(h => h.red <= 12 && h.green <= 13 && h.blue <= 14) ) .map(_.id) .sum println(res) def part2 = val res = getGames.map(_.power).sum println(res) @main def Day2(part: Int) = part match case 1 => part1 case 2 => part2