/* Advent of Code 2024 in Picat. Problem 6 https://adventofcode.com/2024/day/6 Only Part 2 This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import aoc_utils. main => go. /* 1min:06.4s */ go => garbage_collect(300_000_000), File = "6.txt", M = {Line.to_array: Line in read_file_lines(File)}, Rows = M.len, Cols = M[1].len, LoopCount = 0, [[StartX,StartY]] = [[I,J] : I in 1..Rows, J in 1..Cols, M[I,J] = '^'], foreach(I in 1..Rows, J in 1..Cols, (I != StartX ; J != StartY)) if M[I,J] != '#' then M2 = copy_term(M), M2[I,J] := '#', Loop = walk(M2,Rows,Cols,I,J), if Loop then LoopCount := LoopCount+1 end end end, println(LoopCount). walk(M,Rows,Cols,XI,YI) = Loop => garbage_collect(300_000_000), [[X,Y]] = [[I,J] : I in 1..Rows, J in 1..Cols, M[I,J] = '^'], Dir = north, OK = true, Loop = false, Seen = new_set(), while (check(Rows,Cols,X,Y), OK == true, Loop == false) [NewX,NewY] = fd(Dir,X,Y), if not check(Rows,Cols,NewX,NewY) then OK := false end, if Seen.has_key([X,Y,Dir]) then Loop := true end, Seen.put([X,Y,Dir]), if OK then if M[NewX,NewY] == '#' then NewDir = rot(Dir), Dir := NewDir else X := NewX, Y := NewY end end end. check(Rows,Cols,X,Y) => X >= 1, X <= Rows, Y >= 1, Y <= Cols. print_matrix(M) => foreach(Row in M) println(Row) end, nl. fd(north,X,Y) = [X-1,Y]. fd(east,X,Y) = [X,Y+1]. fd(south,X,Y) = [X+1,Y]. fd(west,X,Y) = [X,Y-1]. % Current position and then 90 degrees rot(north) = east. rot(east) = south. rot(south) = west. rot(west) = north.