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()