1
0
Fork 0

solve 2021 day 9

This commit is contained in:
Sloane Perrault 2022-09-21 09:19:53 -04:00
parent 210ff58be5
commit 245282f522
2 changed files with 91 additions and 1 deletions

View file

@ -15,7 +15,7 @@
| S | M | T | W | T | F | S | | S | M | T | W | T | F | S |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| | | | [1] | [2] | [3] | [4] | | | | | [1] | [2] | [3] | [4] |
| [5] | [6] | [7] | [8] | 9 | 10 | 11 | | [5] | [6] | [7] | [8] | [9] | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
@ -29,3 +29,4 @@
[6]: ./lib/2021/6.ex [6]: ./lib/2021/6.ex
[7]: ./lib/2021/7.ex [7]: ./lib/2021/7.ex
[8]: ./lib/2021/8.ex [8]: ./lib/2021/8.ex
[9]: ./lib/2021/9.ex

89
2021/lib/2021/9.ex Normal file
View file

@ -0,0 +1,89 @@
import AOC
aoc 2021, 9 do
def input_map(),
do:
input_string()
|> String.split("\n")
|> Enum.with_index()
|> Enum.flat_map(fn {line, i} ->
line
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
|> Enum.with_index()
|> Enum.map(fn {cell, j} -> {{i, j}, cell} end)
end)
|> Map.new()
def n({i, j}), do: {i - 1, j}
def e({i, j}), do: {i, j + 1}
def s({i, j}), do: {i + 1, j}
def w({i, j}), do: {i, j - 1}
def at(map, pos), do: Map.get(map, pos, :infinity)
def directions(), do: [&n/1, &e/1, &s/1, &w/1]
def neighbors(map, origin) do
for d <- directions(), pos = d.(origin) do
{pos, at(map, pos)}
end
end
def gt({_, a}, b), do: a > b
def basin_from(map, pos, seen \\ MapSet.new()) do
curr = at(map, pos)
if min(curr, 9) == 9 do
MapSet.new()
else
seen = MapSet.put(seen, pos)
inclines =
neighbors(map, pos)
|> Enum.filter(&gt(&1, curr))
|> Enum.map(&elem(&1, 0))
for inc <- inclines, reduce: seen do
seen ->
if MapSet.member?(seen, inc) do
seen
else
MapSet.union(seen, basin_from(map, inc, seen))
end
end
end
end
def p1 do
map = input_map()
for i <- 0..99, j <- 0..99 do
pos = {i, j}
curr = at(map, pos)
neighbors =
directions()
|> Enum.map(fn d -> at(map, d.(pos)) end)
if Enum.all?(neighbors, &(curr < &1)) do
curr + 1
else
0
end
end
|> Enum.sum()
end
def p2 do
map = input_map()
for i <- 0..99, j <- 0..99, pos = {i, j} do
basin_from(map, pos) |> MapSet.size()
end
|> Enum.sort(:desc)
|> Enum.take(3)
|> Enum.product()
end
end