Day 11: remove debug code, simpler datastructure

This commit is contained in:
Adam Millerchip 2020-12-11 19:16:24 +09:00
parent 212e979cbd
commit dba1986b34
2 changed files with 82 additions and 119 deletions

View file

@ -5,52 +5,47 @@ defmodule Day11Part1 do
|> Enum.map(&String.to_charlist/1) |> Enum.map(&String.to_charlist/1)
|> parse_seat_plan() |> parse_seat_plan()
|> run_until_stable() |> run_until_stable()
|> elem(2)
|> count_occupied() |> count_occupied()
|> IO.inspect() |> IO.inspect()
end end
def run_until_stable(state) do def run_until_stable(seats) do
new_state = tick(state) new_seats = tick(seats)
if new_state == state do if new_seats == seats do
state seats
else else
run_until_stable(new_state) run_until_stable(new_seats)
end end
end end
def tick({width, height, old_seats}) do def tick(seats) do
new_seats = Map.new(seats, fn {{x, y}, old_seat} -> toggle(old_seat, x, y, seats) end)
for(
x <- 0..(width - 1),
y <- 0..(height - 1),
do: {x, y}
)
|> Enum.reduce(%{}, fn {x, y}, new_seats ->
toggle(old_seats[{x, y}], x, y, old_seats, new_seats)
end)
{width, height, new_seats}
end end
def toggle(:empty, x, y, old_seats, new_seats) do def toggle(:empty, x, y, seats) do
if occupied_adjacent(x, y, old_seats) == 0 do new_value =
Map.put(new_seats, {x, y}, :occupied) if occupied_adjacent(x, y, seats) == 0 do
else :occupied
Map.put(new_seats, {x, y}, :empty) else
end :empty
end
{{x, y}, new_value}
end end
def toggle(:occupied, x, y, old_seats, new_seats) do def toggle(:occupied, x, y, seats) do
if occupied_adjacent(x, y, old_seats) >= 4 do new_value =
Map.put(new_seats, {x, y}, :empty) if occupied_adjacent(x, y, seats) >= 4 do
else :empty
Map.put(new_seats, {x, y}, :occupied) else
end :occupied
end
{{x, y}, new_value}
end end
def toggle(:floor, x, y, _, new_seats), do: Map.put(new_seats, {x, y}, :floor) def toggle(:floor, x, y, _), do: {{x, y}, :floor}
def occupied_adjacent(x, y, seats) do def occupied_adjacent(x, y, seats) do
adjacent = [ adjacent = [
@ -74,37 +69,24 @@ defmodule Day11Part1 do
end end
def parse_seat_plan(input) do def parse_seat_plan(input) do
Enum.reduce(input, {0, 0, %{}}, fn row, {_x, y, seats} -> {_, seats} =
{x, seats} = Enum.reduce(input, {0, %{}}, fn row, {y, seats} ->
Enum.reduce(row, {0, seats}, fn seat, {x, seats} -> {_, seats} =
seat = Enum.reduce(row, {0, seats}, fn seat, {x, seats} ->
case seat do seat =
?L -> :empty case seat do
?. -> :floor ?L -> :empty
end ?. -> :floor
?# -> :occupied
end
{x + 1, Map.put(seats, {x, y}, seat)} {x + 1, Map.put(seats, {x, y}, seat)}
end) end)
{x, y + 1, seats} {y + 1, seats}
end) end)
end
def visualize({width, height, seats}) do seats
for y <- 0..(height - 1) do
for x <- 0..(width - 1) do
char =
case seats[{x, y}] do
:empty -> "L"
:floor -> "."
:occupied -> "#"
end
IO.write(char)
end
IO.write("\n")
end
end end
end end

View file

@ -5,52 +5,47 @@ defmodule Day11Part2 do
|> Enum.map(&String.to_charlist/1) |> Enum.map(&String.to_charlist/1)
|> parse_seat_plan() |> parse_seat_plan()
|> run_until_stable() |> run_until_stable()
|> elem(2)
|> count_occupied() |> count_occupied()
|> IO.inspect() |> IO.inspect()
end end
def run_until_stable(state) do def run_until_stable(seats) do
new_state = tick(state) new_seats = tick(seats)
if new_state == state do if new_seats == seats do
state seats
else else
run_until_stable(new_state) run_until_stable(new_seats)
end end
end end
def tick({width, height, old_seats}) do def tick(seats) do
new_seats = Map.new(seats, fn {{x, y}, old_seat} -> toggle(old_seat, x, y, seats) end)
for(
x <- 0..(width - 1),
y <- 0..(height - 1),
do: {x, y}
)
|> Enum.reduce(%{}, fn {x, y}, new_seats ->
toggle(old_seats[{x, y}], x, y, old_seats, new_seats)
end)
{width, height, new_seats}
end end
def toggle(:empty, x, y, old_seats, new_seats) do def toggle(:empty, x, y, seats) do
if occupied_visible(x, y, old_seats) == 0 do new_value =
Map.put(new_seats, {x, y}, :occupied) if occupied_visible(x, y, seats) == 0 do
else :occupied
Map.put(new_seats, {x, y}, :empty) else
end :empty
end
{{x, y}, new_value}
end end
def toggle(:occupied, x, y, old_seats, new_seats) do def toggle(:occupied, x, y, seats) do
if occupied_visible(x, y, old_seats) >= 5 do new_value =
Map.put(new_seats, {x, y}, :empty) if occupied_visible(x, y, seats) >= 5 do
else :empty
Map.put(new_seats, {x, y}, :occupied) else
end :occupied
end
{{x, y}, new_value}
end end
def toggle(:floor, x, y, _, new_seats), do: Map.put(new_seats, {x, y}, :floor) def toggle(:floor, x, y, _), do: {{x, y}, :floor}
def occupied_visible(x, y, seats) do def occupied_visible(x, y, seats) do
directions = [ directions = [
@ -83,38 +78,24 @@ defmodule Day11Part2 do
end end
def parse_seat_plan(input) do def parse_seat_plan(input) do
Enum.reduce(input, {0, 0, %{}}, fn row, {_x, y, seats} -> {_, seats} =
{x, seats} = Enum.reduce(input, {0, %{}}, fn row, {y, seats} ->
Enum.reduce(row, {0, seats}, fn seat, {x, seats} -> {_, seats} =
seat = Enum.reduce(row, {0, seats}, fn seat, {x, seats} ->
case seat do seat =
?L -> :empty case seat do
?. -> :floor ?L -> :empty
?# -> :occupied ?. -> :floor
end ?# -> :occupied
end
{x + 1, Map.put(seats, {x, y}, seat)} {x + 1, Map.put(seats, {x, y}, seat)}
end) end)
{x, y + 1, seats} {y + 1, seats}
end) end)
end
def visualize({width, height, seats}) do seats
for y <- 0..(height - 1) do
for x <- 0..(width - 1) do
char =
case seats[{x, y}] do
:empty -> "L"
:floor -> "."
:occupied -> "#"
end
IO.write(char)
end
IO.write("\n")
end
end end
end end