Skip to content

Instantly share code, notes, and snippets.

@nathanjohnson320
Last active December 1, 2016 21:58
Show Gist options
  • Save nathanjohnson320/b996978bc6974bdecd583ef61fb67b37 to your computer and use it in GitHub Desktop.
Save nathanjohnson320/b996978bc6974bdecd583ef61fb67b37 to your computer and use it in GitHub Desktop.
Code for http://adventofcode.com/ day 1
defmodule Adventof.Day1 do
defp direction("R", :north), do: :east
defp direction("R", :east), do: :south
defp direction("R", :south), do: :west
defp direction("R", :west), do: :north
defp direction("L", :north), do: :west
defp direction("L", :east), do: :north
defp direction("L", :south), do: :east
defp direction("L", :west), do: :south
defp travel(:north, {x, y}, number_of_blocks), do: { x, y + number_of_blocks, :north, Enum.map(y + 1..y + number_of_blocks, fn(ny) -> { x, ny } end) }
defp travel(:south, {x, y}, number_of_blocks), do: { x, y - number_of_blocks, :south, Enum.map(y - 1..y - number_of_blocks, fn(ny) -> { x, ny } end) }
defp travel(:east, {x, y}, number_of_blocks), do: { x + number_of_blocks, y, :east, Enum.map(x + 1..x + number_of_blocks, fn(nx) -> { nx, y } end) }
defp travel(:west, {x, y}, number_of_blocks), do: { x - number_of_blocks, y, :west, Enum.map(x - 1..x - number_of_blocks, fn(nx) -> { nx, y } end)}
defp parse_directions(d, "R" <> rest), do: { direction("R", d), String.to_integer(rest) }
defp parse_directions(d, "L" <> rest), do: { direction("L", d), String.to_integer(rest) }
defp parse_input do
File.read!("./day1/input.txt")
|> String.trim
|> String.split(", ")
end
def p1 do
{x, y, _} = parse_input
|> Enum.reduce({0,0,:north}, fn(directions, {x, y, d}) ->
{current_direction, number_of_blocks} = parse_directions(d, directions)
{x,y,d,_} = travel(current_direction, {x, y}, number_of_blocks)
{x,y,d}
end)
abs(x) + abs(y)
end
def p2 do
parse_input
|> Enum.reduce_while({0,0,:north,[]}, fn(directions, {x, y, d, visited_nodes}) ->
{current_direction, number_of_blocks} = parse_directions(d, directions)
{x,y,d,new_visited} = travel(current_direction, {x, y}, number_of_blocks)
visited = already_visited(new_visited, visited_nodes)
if not is_nil(visited) do
{:halt, visited}
else
{:cont, { x, y, d, new_visited ++ visited_nodes }}
end
end)
end
defp already_visited(sub_nodes, nodes) do
Enum.find_value(sub_nodes, fn({x,y}) ->
if Enum.member?(nodes, {x,y}) do
abs(x) + abs(y)
end
end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment