/* Advent of Code 2024 in Picat. Problem 3 https://adventofcode.com/2024/day/3 Note: This program uses my regex module: https://github.com/hakank/picat_regex Compared to 3.pi and 3b.pi here are some other versions of part 1 and part 2. Part 2 is quite neater than in 3.pi and 3b.pi This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import regex. import aoc_utils. main => go. /* Part 1 and part 2 combined. Hyperfine Benchmark 1: picat -g go 3c.pi Time (mean ± σ): 37.6 ms ± 7.7 ms [User: 20.4 ms, System: 17.1 ms] Range (min … max): 18.5 ms … 49.0 ms 55 runs */ go => Chars = read_file_chars("3.txt"), % Part 1 X = regex_find_all("mul\\((\\d+?),(\\d+?)\\)",Chars), [A.to_int*B.to_int : [A,B] in X].sum.println(), % Part 2 s(X,true,0,S), % part2b println(S). /* Part 1 Hyperfine Benchmark 1: picat -g part1 3c.pi Time (mean ± σ): 36.9 ms ± 5.2 ms [User: 19.0 ms, System: 17.8 ms] Range (min … max): 22.4 ms … 45.4 ms 63 runs */ part1 => X = regex_find_all("mul\\((\\d+?),(\\d+?)\\)",read_file_chars("3.txt")), [A.to_int*B.to_int : [A,B] in X].sum.println(). /* Part 2 This is a neater imperative variant compared to the one in 3.pi and 3b.pi Hyperfine Benchmark 1: picat -g part2 3c.pi Time (mean ± σ): 38.4 ms ± 6.0 ms [User: 20.8 ms, System: 17.5 ms] Range (min … max): 22.5 ms … 49.2 ms 57 runs */ part2 => File = "3.txt", X = regex_find_all("mul\\((\\d+?),(\\d+?)\\)|do\\(\\)|don't\\(",read_file_chars(File)), State = true, S = 0, foreach(P in X) if P == "do()" then State := true elseif P == "don't(" then State := false else if State then S := S + P.map(to_int).prod end end, end, println(S). /* Part 2 b Variant using recursion. Hyperfine Benchmark 1: picat -g part2b 3c.pi Time (mean ± σ): 35.7 ms ± 7.5 ms [User: 18.5 ms, System: 17.1 ms] Range (min … max): 18.4 ms … 49.8 ms 52 runs */ part2b => File = "3.txt", X = regex_find_all("mul\\((\\d+?),(\\d+?)\\)|do\\(\\)|don't\\(",read_file_chars(File)), s(X,true,0,S), println(S). s([],Status,S,S). s([P|Xs],true,S0,S) :- ( P.len==2 -> s(Xs,true,S0+P.map(to_int).prod,S) ; P == "don't(" -> s(Xs,false,S0,S) ; s(Xs,true,S0,S) ). s([P|Xs],false,S0,S) :- ( P == "do()" -> s(Xs,true,S0,S) ; s(Xs,false,S0,S) ).