Advent of Code 2021 - Day 5
Setup
Mix.install([
{:kino, "~> 0.4.1"}
])
:ok
example_input = Kino.Input.textarea("Please enter the example input:")
my_input = Kino.Input.textarea("Please enter your input:")
defmodule Parser do
def parse_input(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(&String.trim/1)
|> Enum.flat_map(&String.split(&1, " -> ", trim: true))
|> Enum.flat_map(&String.split(&1, ","))
|> Enum.map(&String.to_integer/1)
|> Enum.chunk_every(2)
|> Enum.map(&List.to_tuple/1)
|> Enum.chunk_every(2)
|> Enum.map(&List.to_tuple/1)
end
end
example_input =
example_input
|> Kino.Input.read()
|> Parser.parse_input()
my_input =
my_input
|> Kino.Input.read()
|> Parser.parse_input()
:ok
:ok
Part 1
my_input
|> Enum.filter(fn {{from_row, from_col}, {to_row, to_col}} ->
from_row == to_row or from_col == to_col
end)
# |> IO.inspect()
|> Enum.flat_map(fn {{from_row, from_col}, {to_row, to_col}} ->
for row <- from_row..to_row,
col <- from_col..to_col do
{row, col}
end
end)
|> Enum.frequencies()
# |> IO.inspect()
|> Enum.filter(fn {_point, count} -> count > 1 end)
|> Enum.count()
5092
Part 2
I’m having trouble getting this to finish. If I use this point generation function in part 1, part 1 runs faster. So the problem isn’t that the point generation algorithm is slower than the one in part 1, the problem is its not fast enough to handle the lines we aren’t ignoring anymore.
Apparently, modules are faster because they actually get compiled. This runs much faster.
defmodule Day5.Part1 do
def solve(input) do
input
|> Enum.filter(fn {{from_row, from_col}, {to_row, to_col}} ->
from_row == to_row or from_col == to_col
end)
# |> IO.inspect()
|> Enum.flat_map(fn {{from_row, from_col}, {to_row, to_col}} ->
for row <- from_row..to_row,
col <- from_col..to_col do
{row, col}
end
end)
|> Enum.frequencies()
|> Enum.filter(fn {_point, count} -> count > 1 end)
|> Enum.count()
end
end
Day5.Part1.solve(my_input)
5092
defmodule Day5.Part2 do
def solve(input) do
input
|> Enum.flat_map(fn {{from_row, from_col}, {to_row, to_col}} ->
distance = Enum.max([abs(from_row - to_row), abs(from_col - to_col)])
for step <- 0..distance do
row =
cond do
from_row == to_row -> from_row
from_row < to_row -> from_row + step
true -> from_row - step
end
col =
cond do
from_col == to_col -> from_col
from_col < to_col -> from_col + step
true -> from_col - step
end
{row, col}
end
end)
# |> IO.inspect()
|> Enum.frequencies()
# |> IO.inspect()
|> Enum.count(fn {_point, count} -> count > 1 end)
end
end
Day5.Part2.solve(my_input)
# |> IO.inspect()
20484