-defmodule Vec, do: defstruct x: 0, y: 0
+defmodule Int do
+  def to_unit(n) do
+    case n do
+      0 -> 0
+      x when x < 0 -> -1
+      _ -> 1
+    end
+  end
+end
 
+defmodule Vec do
+  
+  defstruct x: 0, y: 0
+
+  def origin, do: %Vec{}
+  def subtract(from, other), do: %Vec{x: other.x - from.x, y: other.y - from.y}
+  def magnitude(v), do: v.x + v.y
+  def manhattan_distance(vec1, vec2), do: Vec.subtract(vec1, vec2) |> Vec.magnitude
+  def to_unit(vec), do: %Vec{x: Int.to_unit(vec.x), y: Int.to_unit(vec.y)}
+
+  def move(position, direction), do: %Vec{x: position.x + direction.x, y: position.y + direction.y}
+  def move(position, unit_direction, distance) do
+    position |> move(%Vec{x: unit_direction.x * distance, y: unit_direction.y * distance})
+  end
+
+  @doc """
+  Walk from start to finish, which must be on a horizontal or vertical line from start.
+  Returns the steps taken
+  """
+  def walk(start, finish) do
+    unit = Vec.to_unit(start |> Vec.subtract(finish))
+    distance = Vec.manhattan_distance(start, finish) |> abs
+    1..distance |> Enum.map(&(Vec.move(start, unit, &1)))
+  end
+
+end
+ 
 defimpl String.Chars, for: Vec do
   def to_string(v), do: "{#{v.x}, #{v.y}}" 
 end

            :cont,
            %{
              # Add the steps we've walked to the set of visited nodes
              visited: MapSet.union(acc.visited, MapSet.new(w)),
              position: new_position,
              direction: new_direction
            }

    parse_move_list(input)
    |> Enum.reduce_while(
      %{
        visited: MapSet.new([Vec.origin]),
        position: Vec.origin,
        direction: @n
      },
      fn (step, acc) ->

        # Which direction will we be facing after modifying our current direction with the move's direction?
        new_direction = turn(acc.direction, step.turn_direction)

        # After moving in new_direction by the move's number of steps, where are we?
        new_position = acc.position |> Vec.move(new_direction, step.distance)

        # What is the path from where we were to where we are now?
        path = acc.position |> Vec.walk(new_position)

        # Debug...
        # IO.puts "#{inspect step} -> #{inspect new_direction} Walking #{inspect w}"

        crossing = first_visited_path_element(path, acc.visited)

        case crossing do
          nil -> {
