Day 3
This commit is contained in:
110
lib/day3.ex
Normal file
110
lib/day3.ex
Normal file
@@ -0,0 +1,110 @@
|
||||
defmodule Aoc2023.Day3 do
|
||||
use Aoc2023
|
||||
|
||||
@symbols [
|
||||
?$,
|
||||
?%,
|
||||
?&,
|
||||
?*,
|
||||
?+,
|
||||
?-,
|
||||
?/,
|
||||
?=,
|
||||
?@,
|
||||
?#
|
||||
]
|
||||
|
||||
defp adjacents({y, x, len}, grid) do
|
||||
[
|
||||
{y, x - 1},
|
||||
{y, x + len}
|
||||
| for(y <- [y - 1, y + 1], x <- (x - 1)..(x + len), do: {y, x})
|
||||
]
|
||||
|> Enum.filter(fn {y, x} ->
|
||||
0 <= y and y < length(grid) and 0 <= x and x < length(Enum.at(grid, y))
|
||||
end)
|
||||
end
|
||||
|
||||
defp adjacents({y, x}, grid), do: adjacents({y, x, 1}, grid)
|
||||
|
||||
defp get({y, x}, grid) do
|
||||
grid |> Enum.at(y) |> Enum.at(x)
|
||||
end
|
||||
|
||||
defp get({y, x, len}, grid) do
|
||||
x..(x + len - 1) |> Enum.map(&get({y, &1}, grid))
|
||||
end
|
||||
|
||||
defp contains({y, x}, numbers) do
|
||||
numbers
|
||||
|> Enum.filter(fn {ny, nx, nlen} -> ny == y and nx <= x and x < nx + nlen end)
|
||||
end
|
||||
|
||||
defp number(num, grid) do
|
||||
num
|
||||
|> get(grid)
|
||||
|> Enum.map(&(&1 - ?0))
|
||||
|> Integer.undigits()
|
||||
end
|
||||
|
||||
def parse(input) do
|
||||
grid =
|
||||
input
|
||||
|> String.split("\n")
|
||||
|> Enum.map(&String.to_charlist/1)
|
||||
|
||||
{
|
||||
grid,
|
||||
grid
|
||||
|> Enum.with_index()
|
||||
|> Enum.flat_map(fn {row, y} ->
|
||||
row
|
||||
|> runs(&(?0 <= &1 && &1 <= ?9))
|
||||
|> Enum.map(fn {x, len} -> {y, x, len} end)
|
||||
end)
|
||||
}
|
||||
end
|
||||
|
||||
def part1({grid, numbers}) do
|
||||
numbers
|
||||
|> Enum.map(id &&& adjacents(grid))
|
||||
|> Enum.filter(
|
||||
pipe(
|
||||
elem(1)
|
||||
|> Enum.any?(&(get(&1, grid) in @symbols))
|
||||
)
|
||||
)
|
||||
|> Enum.map(
|
||||
pipe(
|
||||
elem(0)
|
||||
|> number(grid)
|
||||
)
|
||||
)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def part2({grid, numbers}) do
|
||||
grid
|
||||
|> Enum.with_index()
|
||||
|> Enum.flat_map(fn {row, y} ->
|
||||
row
|
||||
|> Enum.with_index()
|
||||
|> Enum.filter(&(elem(&1, 0) == ?*))
|
||||
|> Enum.map(&{y, elem(&1, 1)})
|
||||
|> Enum.map(id &&& adjacents(grid))
|
||||
|> Enum.map(pipe(
|
||||
elem(1)
|
||||
|> Enum.flat_map(pipe(contains(numbers)))
|
||||
|> Enum.uniq()
|
||||
))
|
||||
|> Enum.filter(pipe(
|
||||
length()
|
||||
|> then(&(&1 == 2)))
|
||||
)
|
||||
|> Enum.map(pipe(
|
||||
Enum.map(pipe(number(grid))) |> Enum.product
|
||||
))
|
||||
end)
|
||||
|> Enum.sum
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user