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

AoC Day 3 - 2023

2023/day3.livemd

AoC Day 3 - 2023

Mix.install([
  {:kino, "~> 0.12.2"},
  {:kino_aoc, "~> 0.1.6"}
])

Section

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2023", "3", System.fetch_env!("LB_AOC_SESSION"))
example_input =
  """
  467..114..
  ...*......
  ..35..633.
  ......#...
  617*......
  .....+.58.
  ..592.....
  ......755.
  ...$.*....
  .664.598..
  """
engine =
  example_input
  |> String.split("\n")
  |> Enum.with_index()
numbers =
  engine
  |> Enum.flat_map(fn {line, y} ->
    Regex.scan(~r/\d+/, line, return: :index)
    |> List.flatten()
    |> Enum.map(fn {x, length} ->
      {(x - 1)..(x + length), (y - 1)..(y + 1),
       String.slice(line, x, length) |> String.to_integer()}
    end)
  end)
symbols =
  engine
  |> Enum.flat_map(fn {line, y} ->
    Regex.scan(~r/[^\d^\.]/, line, capure: :all_but_first, return: :index)
    |> List.flatten()
    |> Enum.map(fn {x, _} -> {x, y, String.slice(line, x, 1)} end)
  end)
list_adjacent_numbers = fn x, y, numbers ->
  numbers
  |> Stream.filter(fn {cols, rows, _number} -> x in cols and y in rows end)
  |> Enum.map(fn {_rows, _cols, number} -> number end)
end

symbols
|> Stream.flat_map(fn {x, y, _symbol} -> list_adjacent_numbers.(x, y, numbers) end)
|> Enum.sum()
symbols
|> Stream.filter(fn {_x, _y, symbol} -> symbol == "*" end)
|> Stream.map(fn {x, y, _symbol} -> list_adjacent_numbers.(x, y, numbers) end)
|> Stream.filter(fn numbers -> Enum.count(numbers) >= 2 end)
|> Stream.map(fn [a, b] -> a * b end)
|> Enum.sum()