Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of code day 08

2022/livebooks/day-08.livemd

Advent of code day 08

Mix.install([
  {:kino, "~> 0.5.0"}
])

Setup input

input = Kino.Input.textarea("Please paste your input file:")
index =
  input
  |> Kino.Input.read()
  |> String.split("\n")
  |> Enum.with_index()
  |> Enum.count()

index = index - 1

grid =
  input
  |> Kino.Input.read()
  |> String.split("\n")
  |> Enum.with_index()
  |> Enum.reduce(%{}, fn {row, row_num}, map ->
    row
    |> String.graphemes()
    |> Enum.with_index()
    |> Map.new(fn {height, col_num} -> {{row_num, col_num}, String.to_integer(height)} end)
    |> Map.merge(map)
  end)

Part 01

grid
|> Enum.map(fn {{row_num, col_num}, height} ->
  if row_num == 0 || row_num == index || col_num == 0 || col_num == index do
    true
  else
    Enum.any?([
      for(col_num <- 0..(col_num - 1), do: Map.get(grid, {row_num, col_num}) < height)
      |> Enum.all?(),
      for(col_num <- (col_num + 1)..index, do: Map.get(grid, {row_num, col_num}) < height)
      |> Enum.all?(),
      for(row_num <- 0..(row_num - 1), do: Map.get(grid, {row_num, col_num}) < height)
      |> Enum.all?(),
      for(row_num <- (row_num + 1)..index, do: Map.get(grid, {row_num, col_num}) < height)
      |> Enum.all?()
    ])
  end
end)
|> Enum.filter(&amp; &amp;1)
|> Enum.count()

Part 02

grid
|> Enum.map(fn {{row_num, col_num}, height} ->
  if row_num == 0 || row_num == index || col_num == 0 || col_num == index do
    0
  else
    [
      for(col_num <- (col_num - 1)..0, do: Map.get(grid, {row_num, col_num})),
      for(col_num <- (col_num + 1)..index, do: Map.get(grid, {row_num, col_num})),
      for(row_num <- (row_num - 1)..0, do: Map.get(grid, {row_num, col_num})),
      for(row_num <- (row_num + 1)..index, do: Map.get(grid, {row_num, col_num}))
    ]
    |> Enum.reduce(1, fn direction, product ->
      visible =
        direction
        |> Enum.take_while(fn tree -> tree < height end)
        |> (fn blocked -> min(length(blocked) + 1, length(direction)) end).()

      visible * product
    end)
  end
end)
|> Enum.max()