diff --git a/2023/lib/2023/10.ex b/2023/lib/2023/10.ex new file mode 100644 index 0000000..ff661a6 --- /dev/null +++ b/2023/lib/2023/10.ex @@ -0,0 +1,87 @@ +import AOC +# import AOCHelpers +# alias AOCHelpers.Grid + +aoc 2023, 10 do + def p1(input) do + # grid = Grid.to_grid(input) + + # start = Grid.find_value(grid, "S") + + # longest_in_cycle(grid, start) + end + + def p2(_input) do + end + + # def find_cycle(grid, start), do: find_cycle(grid, start, start) + # def find_cycle(grid, pos, start, path \\ []) do + # path = [pos | path] + + # neighbors = + # grid + # |> Grid.neighbors(pos) + # |> Enum.filter(&connects?/1) + # |> Enum.reject(fn {coords, _, _} -> coords in path end) + # |> Enum.map(&elem(&1, 0)) + + # case neighbors + + # end + + # def longest_in_cycle(grid, pos, seen \\ %{}, dist \\ 0) do + # seen = Map.update(seen, pos, dist, &min(&1, dist)) + + # neighbors = + # grid + # |> Grid.neighbors(pos) + # |> Enum.filter(&connects?/1) + # |> Enum.reject(&seen_shorter?(seen, &1, dist + 1)) + + # case neighbors do + # [] -> + # {pos, seen, dist} + + # neighbors -> + # {visited, seen} = + # neighbors + # |> Enum.map_reduce(seen, fn {neighbor, _, _}, seen -> + # {_, seen, _} = result = longest_in_cycle(grid, neighbor, seen, dist + 1) + + # {result, seen} + # end) + + # {pos, _, dist} = Enum.max_by(visited, &elem(&1, 2)) + # {pos, seen, dist} + # end + # end + + # def connects?({_, [:north], p}) when p in ~w[| 7 F], do: true + # def connects?({_, [:east], p}) when p in ~w[- J 7], do: true + # def connects?({_, [:south], p}) when p in ~w[| L J], do: true + # def connects?({_, [:west], p}) when p in ~w[- L F], do: true + # def connects?(_), do: false + + # def seen_shorter?(seen, {coords, _, _}, dist), do: seen_shorter?(seen, coords, dist) + + # def seen_shorter?(seen, coords, dist) do + # case Map.get(seen, coords) do + # nil -> false + # n -> n <= dist + # end + # end + + # def print_grid(grid) do + # grid + # |> Grid.map(fn + # "." -> " " + # "L" -> "└" + # "J" -> "┘" + # "7" -> "┐" + # "F" -> "┌" + # "-" -> "─" + # n -> n + # end) + # |> Grid.inspect() + # end +end diff --git a/2023/lib/aoc_helpers/grid.ex b/2023/lib/aoc_helpers/grid.ex new file mode 100644 index 0000000..f7cf963 --- /dev/null +++ b/2023/lib/aoc_helpers/grid.ex @@ -0,0 +1,108 @@ +defmodule AOCHelpers.Grid do + import AOCHelpers + + defstruct [:map, :bounds] + + def to_grid(str) do + lists = + str + |> lines() + |> Enum.map(&letters/1) + + map = + for {list, y} <- Enum.with_index(lists), {v, x} <- Enum.with_index(list), into: %{} do + {{x, y}, v} + end + + max_x = + map + |> Enum.map(fn {{x, _}, _} -> x end) + |> Enum.max() + + max_y = + map + |> Enum.map(fn {{_, y}, _} -> y end) + |> Enum.max() + + bounds = {0..max_x, 0..max_y} + + %__MODULE__{map: map, bounds: bounds} + end + + def in_bounds?(%__MODULE__{bounds: {min_x..max_x, min_y..max_y}}, {x, y}) do + min_x <= x and x <= max_x and min_y <= y and y <= max_y + end + + def update!(grid, coords, value) do + %__MODULE__{grid | map: Map.update!(grid.map, coords, value)} + end + + def get(grid, coords, default \\ nil) do + Map.get(grid.map, coords, default) + end + + def map(grid, fun) do + map = + Enum.map(grid.map, fn {coords, value} -> + {coords, fun.(value)} + end) + |> Enum.into(%{}) + + %__MODULE__{grid | map: map} + end + + def inspect(%__MODULE__{map: map, bounds: bounds}) do + {xs, ys} = bounds + + for y <- ys, into: "" do + line = + for x <- xs, into: "" do + Map.get(map, {x, y}, " ") + end + + "#{line}\n" + end + |> IO.puts() + end + + def find_value(grid, value) do + with {coords, _} <- Enum.find(grid.map, fn {_, v} -> v == value end) do + coords + end + end + + def find(grid, fun) do + Enum.find(grid.map, fn {_, v} -> fun.(v) end) + end + + def neighbors(grid, coords, diag? \\ false) do + coords + |> neighbor_coords() + |> Enum.filter(fn {c, dirs} -> + if diag? do + in_bounds?(grid, c) + else + in_bounds?(grid, c) and length(dirs) == 1 + end + end) + |> Enum.map(fn {c, dirs} -> + {c, dirs, Map.get(grid.map, c)} + end) + end + + defp neighbor_coords({x, y}) do + for {j, j_dir} <- [{y - 1, [:north]}, {y, []}, {y + 1, [:south]}], + {i, i_dir} <- [{x - 1, [:west]}, {x, []}, {x + 1, [:east]}], + {x, y} != {i, j} do + {{i, j}, j_dir ++ i_dir} + end + end +end + +# defimpl Inspect, for: AOCHelpers.Grid do +# import Inspect.Algebra + +# def inspect(grid, opts) do + +# end +# end