Watch
1
0
Fork
You've already forked advent-of-code
0

Day 11 Part 2

This commit is contained in:
Jeremy Kaplan 2020-12-10 22:49:03 -08:00
commit 38ae43c77d

View file

@ -25,7 +25,7 @@ defmodule Day11 do
end end
defp content(grid, cell) do defp content(grid, cell) do
Map.get(grid, cell, :floor) Map.get(grid, cell, :void)
end end
defp neighbors(grid, {r, c}) do defp neighbors(grid, {r, c}) do
@ -88,6 +88,170 @@ defmodule Day11 do
|> run() |> run()
|> count_seated() |> count_seated()
end end
defp tick2(grid, dims) do
occupied = Enum.filter(grid, fn {_, state} -> state == :occupied end)
neighbors =
Enum.reduce(occupied, %{}, fn {cell, _}, counts ->
visible_cells(grid, cell)
|> Enum.reduce(counts, fn cell, counts ->
count = Map.get(counts, cell, 0)
Map.put(counts, cell, count + 1)
end)
end)
# show_counts(neighbors, dims)
Enum.into(grid, %{}, fn {cell, state} ->
new_state =
case state do
:floor ->
:floor
:empty ->
if Map.get(neighbors, cell, 0) == 0 do
:occupied
else
:empty
end
:occupied ->
if Map.get(neighbors, cell, 0) >= 5 do
:empty
else
:occupied
end
end
{cell, new_state}
end)
end
defp visible_cells(grid, cell) do
[
{-1, -1},
{-1, 0},
{-1, +1},
{0, -1},
{0, +1},
{+1, -1},
{+1, 0},
{+1, +1}
]
|> Enum.flat_map(&ray_segment(grid, cell, &1))
end
defp ray_segment(grid, {rr, cc}, {dr, dc}) do
# Skip current cell
first = {rr + dr, cc + dc}
Stream.iterate(first, fn {r, c} -> {r + dr, c + dc} end)
|> Enum.reduce_while([], fn cell, cells ->
case content(grid, cell) do
:occupied -> {:halt, [cell | cells]}
:empty -> {:halt, [cell | cells]}
:floor -> {:cont, [cell | cells]}
# nothing to see here
:void -> {:halt, cells}
end
end)
end
defp run2(grid, dims = {h, w}) do
# IO.puts("-------------------------")
# show(grid, {h, w})
new_grid = tick2(grid, dims)
if new_grid == grid do
grid
else
run2(new_grid, dims)
end
end
defp show(grid, {h, w}) do
for r <- 0..(h - 1) do
for c <- 0..(w - 1) do
IO.write(content_to_char(content(grid, {r, c})))
end
IO.write("\n")
end
end
defp show_counts(grid, {h, w}) do
for r <- 0..(h - 1) do
for c <- 0..(w - 1) do
IO.write(Map.get(grid, {r, c}, 0))
end
IO.write("\n")
end
end
defp content_to_char(content) do
case content do
:floor -> "."
:empty -> "L"
:occupied -> "#"
end
end
defp test_input do
"""
L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL
"""
end
def part2 do
grid = read_input() |> parse_layout()
h = Enum.map(grid, fn {{r, _c}, _} -> r end) |> Enum.max()
w = Enum.map(grid, fn {{_r, c}, _} -> c end) |> Enum.max()
run2(grid, {h + 1, w + 1})
|> count_seated()
end
def debug_state do
"""
#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##
"""
end
def debug do
grid = debug_state() |> parse_layout()
show(grid, {10, 10})
Map.keys(grid)
|> Enum.filter(fn cell ->
Enum.member?(visible_cells(grid, cell), {0, 6})
end)
|> Enum.into(%{}, fn cell -> {cell, content(grid, cell)} end)
|> IO.inspect()
tick(grid) |> show({10, 10})
end
end end
Day11.part1() |> IO.inspect() Day11.part1() |> IO.inspect()
Day11.part2() |> IO.inspect()