diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..288c495 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.txt +main +.DS_Store diff --git a/day10/main.exs b/day10/main.exs new file mode 100644 index 0000000..e36fa93 --- /dev/null +++ b/day10/main.exs @@ -0,0 +1,61 @@ +defmodule Day10 do + def run do + map = + File.read!("data.txt") + |> String.trim() + |> String.split("\n") + |> Enum.map(fn el -> String.graphemes(el) |> Enum.map(&String.to_integer/1) end) + + height = length(map) + width = length(hd(map)) + + trailheads = + Enum.concat(map) + |> Enum.with_index() + |> Enum.filter(fn {el, _} -> el == 0 end) + |> Enum.map(fn {_, idx} -> {div(idx, height), rem(idx, width)} end) + + paths1 = + Enum.reduce(trailheads, 0, fn th, acc -> + (walk(th, map) |> List.flatten() |> Enum.uniq() |> length) + acc + end) + + dbg(paths1) + + # same as part one, just don't uniq() them + paths2 = + Enum.reduce(trailheads, 0, fn th, acc -> + (walk(th, map) |> List.flatten() |> length) + acc + end) + + dbg(paths2) + end + + defp walk(coord, map) do + value = element_at(coord, map) + + if value == 9 do + coord + else + # find the coords of all neighbors + neighbors(coord) + # filter by whether the element is 1 greater + |> Enum.filter(fn c -> element_at(c, map) == value + 1 end) + # add this path to the list. it'll be empty and then flattened away if it doesn't reach the top + |> Enum.reduce([], fn el, acc -> [walk(el, map) | acc] end) + end + end + + defp neighbors({x, y}) do + [{-1, 0}, {0, 1}, {1, 0}, {0, -1}] + |> Enum.map(fn {dx, dy} -> {x + dx, y + dy} end) + |> Enum.reject(fn {x2, y2} -> x2 < 0 or y2 < 0 end) + end + + defp element_at({x, y}, map) do + row = Enum.at(map, x) + if is_nil(row), do: nil, else: Enum.at(row, y) + end +end + +Day10.run()