Untitled notebook
Section
Mix.install([
{:kino, "~> 0.14.2"}
])
defmodule Griddy do
def enum_to_map(enum) do
Stream.iterate(0, &(&1 + 1)) |> Enum.zip(enum) |> Map.new()
end
def new_from_string(string) do
Griddy.enum_to_map(
string
|> String.split("\n")
|> Enum.map(&String.graphemes/1)
|> Enum.map(&Griddy.enum_to_map/1)
)
end
def reduce(grid, initial, func) do
grid
|> Enum.reduce(initial, fn {y, sub_map}, acc ->
sub_map
|> Enum.reduce(acc, fn {x, value}, acc ->
func.(value, acc, x, y)
end)
end)
end
def map(grid, func) do
grid
|> Enum.map(fn {y, sub_map} ->
new_sub_map =
sub_map
|> Enum.map(fn {x, value} ->
{x, func.(value, x, y)}
end)
|> Map.new()
{y, new_sub_map}
end)
|> Map.new()
end
def get_nearby_cells(grid, x, y) do
above_below_range = -1..1//1
above_below_range
|> Enum.map(fn dy ->
-1..1//1
|> Enum.map(fn dx ->
if dx == 0 && dy == 0 do
nil
else
grid |> Griddy.get(x + dx, y + dy)
end
end)
end)
|> Enum.flat_map(fn a -> a end)
|> Enum.filter(fn a -> a end)
end
def get(grid, x, y) do
grid[y][x]
end
def put(grid, x, y, value) do
grid |> Map.update(y, nil, fn sub_map -> sub_map |> Map.put(x, value) end)
end
def update(grid, x, y, default, func) do
grid |> Map.update(y, nil, fn sub_map -> sub_map |> Map.update(x, default, func) end)
end
def find(map, value) do
map
|> Enum.reduce({0, 0}, fn {y, sub_map}, acc ->
sub_map
|> Enum.reduce(acc, fn {x, _}, acc ->
if map[y][x] == value, do: {x, y}, else: acc
end)
end)
end
def to_string(grid) do
{string, _} =
grid
|> Griddy.reduce({"", nil}, fn value, {acc, prev_y}, _, y ->
if y != prev_y do
{acc <> "\n" <> value, y}
else
{acc <> value, y}
end
end)
string
end
def print(grid) do
grid |> Griddy.to_string() |> IO.puts()
grid
end
end
input = Kino.Input.textarea("Please paste your input file")
grid =
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&String.trim/1)
|> Enum.join("\n")
|> Griddy.new_from_string()
grid |> Griddy.get_nearby_cells(1, 0) |> IO.inspect() |> Enum.count()
grid
|> Griddy.map(fn value, x, y ->
if value == "@" do
grid
|> Griddy.get_nearby_cells(x, y)
|> Enum.filter(fn a ->
a == "@"
end)
|> Enum.count()
else
nil
end
end)
|> IO.inspect()
|> Enum.flat_map(fn a -> a end)
|> Enum.reduce(0, fn {key, value}, acc ->
if value < 4 do
acc + 1
else
acc
end
end)
grid =
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&String.trim/1)
|> Enum.join("\n")
|> Griddy.new_from_string()
initial =
grid
|> Griddy.reduce(0, fn value, acc, x, y ->
if value == "@" do
acc + 1
else
acc
end
end)
final_grid =
1..200
|> Enum.reduce(grid, fn _value, current_grid ->
current_grid
|> Griddy.map(fn value, x, y ->
if value == "@" do
count =
current_grid
|> Griddy.get_nearby_cells(x, y)
|> Enum.filter(fn a ->
a == "@"
end)
|> Enum.count()
if count < 4 do
"."
else
"@"
end
else
"."
end
end)
end)
final_grid |> Griddy.to_string() |> IO.inspect()
final =
final_grid
|> Griddy.reduce(0, fn value, acc, _x, _y ->
if value == "@" do
acc + 1
else
acc
end
end)
initial - final
to low 8950