This commit is contained in:
bluepython508
2023-12-03 11:35:22 +00:00
parent 2ae3b6cf7b
commit ee17acccae
6 changed files with 144 additions and 0 deletions

View File

@@ -12,4 +12,24 @@ defmodule Aoc2023.Common do
fn (val) -> val |> unquote(expr) 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

110
lib/day3.ex Normal file
View 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

View File

@@ -4,6 +4,7 @@ defmodule Mix.Tasks.Aoc do
defp module(1), do: Aoc2023.Day1
defp module(2), do: Aoc2023.Day2
defp module(3), do: Aoc2023.Day3
# [MODULE INSERTION POINT]
defp base_dir(), do: System.get_env("AOC_BASE")
@@ -110,6 +111,7 @@ defmodule Mix.Tasks.Aoc do
:code.purge(module(day))
:code.purge(Aoc2023.Common)
:code.load_file(module(day))
:code.load_file(Aoc2023.Common)
run(day, ["test"])
receive do
:update -> loop.(loop)

10
tests/day3/1 Normal file
View File

@@ -0,0 +1,10 @@
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..

1
tests/day3/1.1 Normal file
View File

@@ -0,0 +1 @@
4361

1
tests/day3/1.2 Normal file
View File

@@ -0,0 +1 @@
467835