AoC 2015 Day 3
Mix.install([:kino])
defmodule Utils do
def split(line, sep \\ "") do
String.split(line, sep, trim: true)
end
def split_all_lines(text, sep \\ "") do
text
|> String.split("\n", trim: true)
|> Enum.map(&split(&1, sep))
end
def to_numbers(number) when is_binary(number) do
String.to_integer(number)
end
def to_numbers(numbers) when is_list(numbers) do
Enum.map(numbers, &to_numbers/1)
end
def to_matrix(text, sep \\ "") do
text
|> split_all_lines(sep)
|> then(fn data ->
for {row, r} <- Enum.with_index(data), {col, c} <- Enum.with_index(row) do
{{r, c}, col}
end
end)
|> Map.new()
end
end
Setup
import Utils
input = Kino.Input.textarea("Input:")
text = Kino.Input.read(input)
data = split(text, "")
P1
p1 = fn data ->
Enum.reduce(data, {{0, 0}, MapSet.new([{0, 0}])}, fn
"^", {{x, y}, s} ->
curr = {x, y + 1}
{curr, MapSet.put(s, curr)}
"v", {{x, y}, s} ->
curr = {x, y - 1}
{curr, MapSet.put(s, curr)}
"<", {{x, y}, s} ->
curr = {x - 1, y}
{curr, MapSet.put(s, curr)}
">", {{x, y}, s} ->
curr = {x + 1, y}
{curr, MapSet.put(s, curr)}
end)
|> elem(1)
end
p1.(data) |> Enum.count()
P2
{flesh, robot} =
data
|> Enum.with_index()
|> Enum.split_with(fn {_, i} -> rem(i, 2) == 0 end)
flesh
|> Enum.map(&elem(&1, 0))
|> p1.()
|> MapSet.union(robot |> Enum.map(&elem(&1, 0)) |> p1.())
|> Enum.count()