! Copyright (C) 2023 CapitalEx. ! See https://factorcode.org/license.txt for BSD license. USING: assocs hashtables io.encodings.utf8 io.files kernel math math.parser multiline pair-rocket peg.ebnf sequences ; IN: aoc.2023.2 : input ( -- string ) "vocab:aoc/2023/2/input.txt" utf8 file-contents ; CONSTANT: bag H{ "red" => 12 "green" => 13 "blue" => 14 } EBNF: parse-game [=[ Digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" Number = Digit+ => [[ concat dec> ]] GameId = "Game "~ Number ": "~ CubeCount = Number " "~ ("red"|"green"|"blue") => [[ reverse ]] SubSet = CubeCount (", "~ CubeCount)* => [[ first2 swap prefix >hashtable ]] SubSets = SubSet ("; "~ SubSet)* => [[ first2 swap prefix ]] Set = GameId SubSets => [[ { "id" "sets" } swap H{ } zip-as ]] ]=] : parse-games ( string -- games ) split-lines [ parse-game ] map ; : valid-game? ( sets -- ? ) "sets" of [ [ swap bag at <= ] assoc-all? ] all? ; : valid-games ( games -- valid ) [ valid-game? ] filter ; inline : game-ids ( games -- ids ) [ "id" of ] map ; inline : solve-part-one ( -- ) input parse-games valid-games game-ids sum . ; : minimum-bag ( game -- minimum-bag ) "sets" of H{ } [ [ max ] assoc-merge ] reduce ; : find-minimum-bags ( games -- bags ) [ minimum-bag ] map ; : sum-of-powers ( games -- power-sum ) [ values product ] map-sum ; : solve-part-two ( -- ) input parse-games find-minimum-bags sum-of-powers . ;