Skip to content

Instantly share code, notes, and snippets.

@ynonp
Created December 12, 2020 11:09
Show Gist options
  • Save ynonp/89f316675304d55b59f30dceac41cbc3 to your computer and use it in GitHub Desktop.
Save ynonp/89f316675304d55b59f30dceac41cbc3 to your computer and use it in GitHub Desktop.
defmodule Ship do
defstruct heading: 90, pos: { 0, 0 }
def distance(ship) do
Tuple.to_list(ship.pos)
|> Enum.map(&(abs(&1)))
|> Enum.sum
end
def move(ship, %{ "dir" => "L", "steps" => degrees}) do
Map.update!(ship, :heading, fn
v when v - degrees < 0 -> rem(v - degrees + 360, 360)
v -> rem(v - degrees, 360)
end)
end
def move(ship, %{ "dir" => "R", "steps" => degrees}) do
Map.update!(ship, :heading, fn v -> rem(v + degrees, 360) end)
end
def move(ship, %{ "dir" => "N", "steps" => steps}) do
Map.update!(ship, :pos, fn { x, y } -> { x, y - steps } end)
end
def move(ship, %{ "dir" => "E", "steps" => steps}) do
Map.update!(ship, :pos, fn { x, y } -> { x + steps, y } end)
end
def move(ship, %{ "dir" => "W", "steps" => steps}) do
Map.update!(ship, :pos, fn { x, y } -> { x - steps, y } end)
end
def move(ship, %{ "dir" => "S", "steps" => steps}) do
Map.update!(ship, :pos, fn { x, y } -> { x, y + steps} end)
end
def move(ship, %{ "dir" => "F", "steps" => steps}) do
case ship.heading do
0 -> move(ship, %{ "dir" => "N", "steps" => steps })
90 -> move(ship, %{ "dir" => "E", "steps" => steps })
180 -> move(ship, %{ "dir" => "S", "steps" => steps })
270 -> move(ship, %{ "dir" => "W", "steps" => steps })
end
end
end
defmodule Day12 do
def read_input do
File.read!("input/day12.txt")
|> String.split("\n", trim: true)
|> Enum.map(&(Regex.named_captures(~r/(?<dir>[NSEWFLR])(?<steps>\d+)/, &1)))
|> IO.inspect
|> Enum.map(&(Map.update!(&1, "steps", fn x -> String.to_integer(x) end)))
end
# def step(ship, { "dir" => dir, "steps" => steps }) do
# end
def part1 do
read_input()
|> Enum.reduce(%Ship{}, fn val, acc -> Ship.move(acc, val) end)
|> IO.inspect
|> Ship.distance
|> IO.inspect
end
end
defmodule Ship2 do
defstruct pos: { 0, 0 }, waypoint: { 10, -1 }
def distance(ship) do
Tuple.to_list(ship.pos)
|> Enum.map(&(abs(&1)))
|> Enum.sum
end
def rotate_clockwise({ x, y }, 0) do
{ x, y }
end
def rotate_clockwise({ x, y }, 90) do
{ -1 * y , x }
end
def rotate_clockwise({ x, y }, 180) do
{ x, y }
|> rotate_clockwise(90)
|> rotate_clockwise(90)
end
def rotate_clockwise({ x, y }, 270) do
{ x, y }
|> rotate_clockwise(90)
|> rotate_clockwise(90)
|> rotate_clockwise(90)
end
def move(ship, %{ "dir" => "L", "steps" => degrees}) do
clockwise = 360 - degrees
Map.update!(ship, :waypoint, &(rotate_clockwise(&1, clockwise)))
end
def move(ship, %{ "dir" => "R", "steps" => degrees}) do
Map.update!(ship, :waypoint, &(rotate_clockwise(&1, degrees)))
end
def move(ship, %{ "dir" => "N", "steps" => steps}) do
Map.update!(ship, :waypoint, fn { x, y } -> { x, y - steps } end)
end
def move(ship, %{ "dir" => "E", "steps" => steps}) do
Map.update!(ship, :waypoint, fn { x, y } -> { x + steps, y } end)
end
def move(ship, %{ "dir" => "W", "steps" => steps}) do
Map.update!(ship, :waypoint, fn { x, y } -> { x - steps, y } end)
end
def move(ship, %{ "dir" => "S", "steps" => steps}) do
Map.update!(ship, :waypoint, fn { x, y } -> { x, y + steps} end)
end
def move(ship, %{ "dir" => "F", "steps" => steps}) do
Map.update!(ship, :pos, fn { x, y } ->
{ x + steps * elem(ship.waypoint, 0), y + steps * elem(ship.waypoint, 1) }
end)
end
end
defmodule Day12part2 do
def read_input do
File.read!("input/day12.txt")
|> String.split("\n", trim: true)
|> Enum.map(&(Regex.named_captures(~r/(?<dir>[NSEWFLR])(?<steps>\d+)/, &1)))
|> IO.inspect
|> Enum.map(&(Map.update!(&1, "steps", fn x -> String.to_integer(x) end)))
end
def go do
read_input()
|> Enum.reduce(%Ship2{}, fn val, acc -> (Ship2.move(acc, val) |> IO.inspect) end)
|> Ship2.distance
|> IO.inspect
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment