module advent_of_code.tasks.day_4.Star2 open System open System.IO let stream = new StreamReader("tasks/day-4/input.txt") let mutable removed = Set.empty let getPos (grid: string list) (pos: int * int) = let y, x = pos.Deconstruct() if (y < 0 || y >= grid.Length || x < 0 || x >= grid[y].Length || removed.Contains((y, x))) then 0 else if grid[y][x] = '@' then 1 else 0 let isMovable (grid: string list) (y: int) (x: int) = if (grid[y][x] = '.' || removed.Contains((y, x))) then false else let posList = [ (y - 1, x - 1); (y - 1, x); (y - 1, x + 1) (y, x - 1); (y, x + 1) (y + 1, x - 1); (y + 1, x); (y + 1, x + 1) ] let adjacentList = posList |> List.map (getPos grid) if (List.sum adjacentList < 4) then removed <- removed.Add((y, x)) true else false let rec countRow (grid: string list) (y: int) (x: int) = if x = grid[y].Length then 0 else (if (isMovable grid y x) then 1 else 0) + (countRow grid y (x + 1)) let rec countGrid (grid: string list) (y: int) = if y = grid.Length then 0 else (countRow grid y 0) + (countGrid grid (y + 1)) let rec loop (grid: string list) = let removables = countGrid grid 0 if removables = 0 then 0 else removables + loop grid let main = let grid = stream.ReadToEnd().Split('\n') |> Array.toList loop grid