Day 3
This commit is contained in:
@@ -12,4 +12,24 @@ defmodule Aoc2023.Common do
|
|||||||
fn (val) -> val |> unquote(expr) end
|
fn (val) -> val |> unquote(expr) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defmacro l &&& r do
|
||||||
|
quote do
|
||||||
|
fn val ->
|
||||||
|
l = val |> unquote(l)
|
||||||
|
r = val |> unquote(r)
|
||||||
|
{l, r}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def runs(lst, f) do
|
||||||
|
lst
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Enum.chunk_by(pipe(elem(0) |> f.()))
|
||||||
|
|> Enum.filter(pipe(Enum.at(0) |> elem(0) |> f.()))
|
||||||
|
|> Enum.map(Enum.at(0) |> elem(1) &&& length)
|
||||||
|
end
|
||||||
|
|
||||||
|
def id(x), do: x
|
||||||
end
|
end
|
||||||
|
|||||||
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
|
||||||
@@ -4,6 +4,7 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
|
|
||||||
defp module(1), do: Aoc2023.Day1
|
defp module(1), do: Aoc2023.Day1
|
||||||
defp module(2), do: Aoc2023.Day2
|
defp module(2), do: Aoc2023.Day2
|
||||||
|
defp module(3), do: Aoc2023.Day3
|
||||||
# [MODULE INSERTION POINT]
|
# [MODULE INSERTION POINT]
|
||||||
|
|
||||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||||
@@ -110,6 +111,7 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
:code.purge(module(day))
|
:code.purge(module(day))
|
||||||
:code.purge(Aoc2023.Common)
|
:code.purge(Aoc2023.Common)
|
||||||
:code.load_file(module(day))
|
:code.load_file(module(day))
|
||||||
|
:code.load_file(Aoc2023.Common)
|
||||||
run(day, ["test"])
|
run(day, ["test"])
|
||||||
receive do
|
receive do
|
||||||
:update -> loop.(loop)
|
:update -> loop.(loop)
|
||||||
|
|||||||
10
tests/day3/1
Normal file
10
tests/day3/1
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
467..114..
|
||||||
|
...*......
|
||||||
|
..35..633.
|
||||||
|
......#...
|
||||||
|
617*......
|
||||||
|
.....+.58.
|
||||||
|
..592.....
|
||||||
|
......755.
|
||||||
|
...$.*....
|
||||||
|
.664.598..
|
||||||
1
tests/day3/1.1
Normal file
1
tests/day3/1.1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
4361
|
||||||
1
tests/day3/1.2
Normal file
1
tests/day3/1.2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
467835
|
||||||
Reference in New Issue
Block a user