/* Advent of Code 2024 in Picat. Problem 12 https://adventofcode.com/2024/day/12 Part 1 This is a faster and shorter version of 12_part1.pi This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. main => go. /* Hyper fine Benchmark 1: picat -g go 12_part1c.pi Time (mean ± σ): 242.2 ms ± 9.7 ms [User: 213.7 ms, System: 28.5 ms] Range (min … max): 223.6 ms … 257.1 ms 11 runs */ go => File = "12.txt", M = read_file_lines(File), Rows = M.len, Cols = M[1].len, Seen = new_set(), Sum = 0, foreach(I in 1..Rows, J in 1..Cols, not Seen.has_key([I,J])) Region = connected_components(M,Seen,Rows,Cols,I,J), Perimeter = perimeter(M,Rows,Cols,Region,M[I,J]), Sum := Sum + Region.len * Perimeter end, println(Sum). % Connected components connected_components(M,Seen,Rows,Cols,I,J) = Rs => Rs = [[I,J]], V = [[I,J]], Seen.put([I,J]), while (V != []) select([A,B],V,V2), foreach([C,D] in neibs(M,Rows,Cols,A,B,M[I,J]), not Seen.has_key([C,D])) V2 := V2 ++ [[C,D]], Rs := Rs ++ connected_components(M,Seen,Rows,Cols,C,D) end, V := V2 end. perimeter(M,Rows,Cols,A,C) = P => Ns = [ [N : N in neibs_chars(M,Rows,Cols,I,J) ] : [I,J] in A].flatten, Same = [1 : I in 1..Ns.len, Ns[I] == C], P = A.len*4 - Same.len. % The indices neibs(M,Rows,Cols,I,J,C) = [[I+A,J+B] : A in -1..1, B in -1..1, abs(A+B) == 1, I+A >= 1, I+A <= Rows, J+B >= 1, J+B <= Cols, M[I+A,J+B] == C]. % The characters neibs_chars(M,Rows,Cols,I,J) = [M[I+A,J+B] : A in -1..1, B in -1..1, abs(A+B) == 1, I+A >= 1, I+A <= Rows, J+B >= 1, J+B <= Cols].