Advent of code day 11
Mix.install([
{:kino, "~> 0.5.0"}
])
Setup input
example = Kino.Input.textarea("Please paste your input example:")
input = Kino.Input.textarea("Please paste your real input:")
defmodule Combinations do
def combinations(_, 0), do: [[]]
def combinations([], _), do: []
def combinations([h | t], r) do
(for combo <- combinations(t, r - 1), do: [h | combo]) ++ combinations(t, r)
end
end
lines =
example
|> Kino.Input.read()
|> String.split("\n", trim: true)
grid =
Enum.map(lines, fn line ->
line
|> String.split("", trim: true)
|> List.to_tuple()
end)
|> List.to_tuple()
total_cols = tuple_size(elem(grid, 0)) - 1
total_rows = (lines |> Enum.count()) - 1
empty_rows=
grid
|> Tuple.to_list()
|> Enum.with_index()
|> Enum.map(fn {row, i} ->
if Tuple.to_list(row) |> Enum.all?(&Kernel.==(&1, ".")), do: i, else: nil
end)
|> Enum.reject(&Kernel.==(&1, nil))
empty_cols =
grid
|> Tuple.to_list()
|> Enum.map(&Tuple.to_list/1)
|> Enum.zip_with(&Function.identity/1)
|> Enum.with_index()
|> Enum.map(fn {row, i} ->
if row |> Enum.all?(&Kernel.==(&1, ".")), do: i, else: nil
end)
|> Enum.reject(&Kernel.==(&1, nil))
points =
for r <- 0..total_rows, c <- 0..total_cols, elem(grid, r) |> elem(c) == "#" do
{r, c}
end
Part 01 & 02
combs = Combinations.combinations(points, 2)
expansion_factor = 1000000
Enum.reduce(combs, 0, fn [{r1, c1}, {r2, c2}], total ->
empty_rows_between =
Enum.count(empty_rows, fn r -> r > min(r1, r2) and r < max(r1, r2) end)
empty_cols_between =
Enum.count(empty_cols, fn c -> c > min(c1, c2) and c < max(c1, c2) end)
base_distance = abs(r1 - r2) + abs(c1 - c2)
expansion = (empty_rows_between + empty_cols_between) * (expansion_factor - 1)
base_distance + expansion + total
end)