46 lines
1.2 KiB
Elixir
46 lines
1.2 KiB
Elixir
import AOC
|
|
|
|
aoc 2015, 3 do
|
|
def input_chars(), do: input_string() |> String.split("", trim: true)
|
|
|
|
def p1 do
|
|
input_chars()
|
|
|> run()
|
|
|> then(fn {visited, _} -> MapSet.size(visited) end)
|
|
end
|
|
|
|
def p2 do
|
|
{santa, robo_santa} =
|
|
input_chars()
|
|
|> Enum.with_index()
|
|
|> Enum.split_with(fn {_, i} -> Integer.mod(i, 2) == 0 end)
|
|
|> then(fn {santa, robo_santa} ->
|
|
{without_index(santa), without_index(robo_santa)}
|
|
end)
|
|
|
|
{visited, _} = run(santa)
|
|
{visited, _} = run(robo_santa, visited)
|
|
|
|
MapSet.size(visited)
|
|
end
|
|
|
|
defp op("^"), do: {1, 0}
|
|
defp op(">"), do: {0, 1}
|
|
defp op("v"), do: {-1, 0}
|
|
defp op("<"), do: {0, -1}
|
|
|
|
defp add({x, y}, {a, b}), do: {x + a, y + b}
|
|
|
|
defp run(inst, visited \\ MapSet.new()) do
|
|
starting_position = {0, 0}
|
|
visited = MapSet.put(visited, starting_position)
|
|
|
|
Enum.reduce(inst, {visited, starting_position}, fn command, {visited, current_position} ->
|
|
current_position = add(current_position, op(command))
|
|
visited = MapSet.put(visited, current_position)
|
|
{visited, current_position}
|
|
end)
|
|
end
|
|
|
|
defp without_index(enum), do: Enum.map(enum, &elem(&1, 0))
|
|
end
|