/* Advent Of Code 2023 Day 2 in Picat. https://adventofcode.com/2023/day/2 Cf 2_dcg.pi for parsing input with DCG. This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. main => go. /* $ hyperfine 'picat 2.pi' Benchmark 1: picat 2.pi Time (mean ± σ): 44.6 ms ± 6.3 ms [User: 27.0 ms, System: 17.6 ms] Range (min … max): 30.2 ms … 54.6 ms 50 runs */ go => part1, part2, nl. /* $ hyperfine 'picat -g part1 2.pi' Benchmark 1: picat -g part1 2.pi Time (mean ± σ): 39.1 ms ± 6.0 ms [User: 23.8 ms, System: 15.2 ms] Range (min … max): 15.9 ms … 48.2 ms 62 runs */ part1 => println("Part 1:"), File = "2.txt", Max = new_map(["red"=12,"green"=13,"blue"=14]), Lines = read_file_lines(File), OKs = [], foreach(Line in Lines) [Id,Cs] = parse_line(Line), OK = true, foreach(Cube in Cs) foreach(Color=Num in Cube, break(OK == false)) if Max.get(Color) < Num then OK := false end end end, if OK then OKs := OKs ++ [Id] end end, println(OKs.sum), nl. /* $ hyperfine 'picat -g part2 2.pi' Benchmark 1: picat -g part2 2.pi Time (mean ± σ): 38.3 ms ± 5.3 ms [User: 23.0 ms, System: 15.3 ms] Range (min … max): 26.9 ms … 48.9 ms 55 runs */ part2 => println("Part 2:"), File = "2.txt", Lines = read_file_lines(File), Prods = [], foreach(Line in Lines) [_Id,Cs] = parse_line(Line), Map = new_map(), foreach(Cube in Cs) foreach(Color=Num in Cube) Map.put(Color,Map.get(Color,[])++[Num]) end end, Prods := Prods ++ [Map.values.map(max).prod] end, println(Prods.sum), nl. parse_line(Line) = [Id.to_int,Cs] => [GameS,Rest1] = Line.split(":"), append("Game ",Id, GameS), append(" ", Rest,Rest1), Cubes = Rest.split(";"), Cs = [], foreach(Cube in Cubes) L = [Color=Num.to_int : [Num,Color] in chunks_of([C.split(" ").first : C in Cube.split(", ")],2)].new_map, Cs := Cs ++ [L] end.