AOC 2022-08 (Treetop Tree House)
Mix.install([
{:kino, "~> 0.7.0"}
])
Input
input = Kino.Input.textarea("Input")
input =
input
|> Kino.Input.read()
|> String.split()
grid =
input
|> Enum.with_index()
|> Enum.reduce(%{}, fn {line, row}, acc ->
line
|> String.graphemes()
|> Enum.with_index()
|> Enum.reduce(acc, fn {height, col}, acc2 ->
Map.put(acc2, {row, col}, String.to_integer(height))
end)
end)
Part 1
Pending refactor...
Part 2
defmodule Grid2 do
@grid_size 99
def find_best_tree_in(grid) do
grid
|> Enum.map(fn {{row, col}, height} ->
all_candidates(row, col)
|> Enum.map(&score(grid, &1, height))
|> Enum.product()
end)
|> Enum.max()
end
defp all_candidates(row, col) do
[
north_candidates(row, col),
south_candidates(row, col),
west_candidates(row, col),
east_candidates(row, col)
]
end
defp north_candidates(row, col) do
Enum.map((row - 1)..0, fn r -> {r, col} end)
end
defp south_candidates(row, col) do
Enum.map((row + 1)..(@grid_size - 1), fn r -> {r, col} end)
end
defp west_candidates(row, col) do
Enum.map((col - 1)..0, fn c -> {row, c} end)
end
defp east_candidates(row, col) do
Enum.map((col + 1)..(@grid_size - 1), fn c -> {row, c} end)
end
def score(grid, partial_row_or_col, height) do
candidates = Enum.map(partial_row_or_col, &height_for_location(grid, &1))
case Enum.find_index(candidates, fn h -> h >= height end) do
nil -> Enum.count(candidates)
other -> other + 1
end
end
defp height_for_location(grid, loc), do: Map.get(grid, loc, 1000)
end
Grid2.find_best_tree_in(grid)