diff --git a/advent-of-code/Program.fs b/advent-of-code/Program.fs index eadb1d7..75fad6e 100644 --- a/advent-of-code/Program.fs +++ b/advent-of-code/Program.fs @@ -16,4 +16,8 @@ let main _ = printfn $"{day3Star1}" let day3Star2 = day_3.Star2.main printfn $"{day3Star2}" + let day4Star1 = day_4.Star1.main + printfn $"{day4Star1}" + let day4Star2 = day_4.Star2.main + printfn $"{day4Star2}" 0 diff --git a/advent-of-code/tasks/day-4/Star1.fs b/advent-of-code/tasks/day-4/Star1.fs new file mode 100644 index 0000000..49dd9c7 --- /dev/null +++ b/advent-of-code/tasks/day-4/Star1.fs @@ -0,0 +1,37 @@ +module advent_of_code.tasks.day_4.Star1 + +open System +open System.IO + +let stream = new StreamReader("tasks/day-4/input.txt") + +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) then + 0 + else + if grid[y][x] = '@' then 1 else 0 + +let isMovable (grid: string list) (y: int) (x: int) = + if (grid[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) + List.sum adjacentList < 4 + +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 main = + let grid = stream.ReadToEnd().Split('\n') |> Array.toList + countGrid grid 0 diff --git a/advent-of-code/tasks/day-4/Star2.fs b/advent-of-code/tasks/day-4/Star2.fs new file mode 100644 index 0000000..c25ea53 --- /dev/null +++ b/advent-of-code/tasks/day-4/Star2.fs @@ -0,0 +1,46 @@ +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