1
0
Fork 0

2021 day 11

This commit is contained in:
Sloane Perrault 2022-09-21 09:19:53 -04:00
parent 7bf97ef3fb
commit 0de9cc93cd
2 changed files with 150 additions and 1 deletions

View file

@ -15,7 +15,7 @@
| S | M | T | W | T | F | S |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| | | | [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 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
@ -31,3 +31,4 @@
[8]: ./lib/2021/8.ex
[9]: ./lib/2021/9.ex
[10]: ./lib/2021/10.ex
[11]: ./lib/2021/11.ex

148
2021/lib/2021/11.ex Normal file
View file

@ -0,0 +1,148 @@
import AOC
aoc 2021, 11 do
use AOCHelpers
@h 10
@w 10
def input() do
lists =
input_string()
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
end)
map =
for {row, i} <- Enum.with_index(lists, 1), {cell, j} <- Enum.with_index(row, 1) do
{{i, j}, cell}
end
|> Map.new()
map
end
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 ne(pos), do: pos |> n() |> e()
def se(pos), do: pos |> s() |> e()
def sw(pos), do: pos |> s() |> w()
def nw(pos), do: pos |> n() |> w()
def neighbor_positions(map, pos) do
[&n/1, &ne/1, &e/1, &se/1, &s/1, &sw/1, &w/1, &nw/1]
|> Enum.map(&apply(&1, [pos]))
|> Enum.filter(&Map.has_key?(map, &1))
end
def neighbor_cells(map, pos) do
neighbor_positions(map, pos)
|> Enum.map(&Map.get(map, &1))
end
def tick(map) do
for {pos, cell} <- map, reduce: map do
acc -> Map.put(acc, pos, cell + 1)
end
|> simulate()
|> then(fn {map, flashes} ->
map =
for {pos, cell} <- map, reduce: map do
map ->
if cell > 9 do
Map.put(map, pos, 0)
else
map
end
end
{map, flashes}
end)
end
def simulate(map) do
flashed =
Enum.filter(map, fn {_, cell} -> cell > 9 end)
|> Enum.map(&elem(&1, 0))
|> MapSet.new()
{map, flashed} =
for pos <- flashed, neighbor <- neighbor_positions(map, pos), reduce: {map, flashed} do
{map, flashed} -> increase_power_level(map, flashed, neighbor)
end
{map, MapSet.size(flashed)}
end
def increase_power_level(map, flashed, pos) do
cell = Map.get(map, pos) + 1
map = Map.put(map, pos, cell)
if cell > 9 and not MapSet.member?(flashed, pos) do
flashed = MapSet.put(flashed, pos)
for neighbor <- neighbor_positions(map, pos), reduce: {map, flashed} do
{map, flashed} -> increase_power_level(map, flashed, neighbor)
end
else
{map, flashed}
end
end
def render_cell(0), do: " "
def render_cell(1), do: "\u2581"
def render_cell(2), do: "\u2582"
def render_cell(3), do: "\u2583"
def render_cell(4), do: "\u2584"
def render_cell(5), do: "\u2585"
def render_cell(6), do: "\u2586"
def render_cell(7), do: "\u2587"
def render_cell(8), do: "\u2588"
def render_cell(9), do: "\u2592"
def render(map) do
for i <- 1..@h do
for j <- 1..@w, cell = Map.get(map, {i, j}), into: "" do
render_cell(cell)
end
end
|> Enum.join("\n")
end
def p1 do
start = input()
{_, flashes} =
for i <- 1..100, reduce: {start, 0} do
{curr, flashes} ->
IO.puts(IO.ANSI.clear())
IO.puts("p1: step #{i}, flashed: #{flashes}")
IO.puts(render(curr))
Process.sleep(50)
{next, new_flashes} = tick(curr)
{next, flashes + new_flashes}
end
flashes
end
def p2 do
start = input()
Stream.unfold({start, 1}, fn {curr, step} ->
IO.puts(IO.ANSI.clear())
IO.puts("p2: step #{step}")
IO.puts(render(curr))
Process.sleep(10)
{next, flashes} = tick(curr)
if flashes == 100, do: nil, else: {{curr, step}, {next, step + 1}}
end)
|> Stream.run()
end
end