DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 12: Rain Risk

Collapse
 
_bigblind profile image
Frederik 👨‍💻➡️🌐 Creemers

I'm gonna post the 2 parts separately, as it looks like it's gonna be easier to edit the code than to support both parts with the same module.

here's part 1:


defmodule Navigator do
  def execute(s, state) do
    inst = String.first(s)
    arg = String.to_integer(String.slice(s, 1, String.length(s)-1))
    execute(inst, arg, state)
  end

  def execute("N", dist, state) do
    Map.merge(state, %{y: state.y + dist})
  end

  def execute("S", dist, state) do
    Map.merge(state, %{y: state.y - dist})
  end

  def execute("E", dist, state) do
    Map.merge(state, %{x: state.x + dist})
  end

  def execute("W", dist, state) do
    Map.merge(state, %{x: state.x - dist})
  end

  def execute("L", angle, state) do
    Map.merge(state, %{dir: state.dir - div(angle, 90)})
  end

  def execute("R", angle, state) do
    Map.merge(state, %{dir: state.dir + div(angle, 90)})
  end

  def execute("F", dist, state) do
    dir = Enum.at(["E", "S", "W", "N"], rem(state.dir, 4))
    execute(dir, dist, state)
  end

  def read_instructions() do
    {:ok, text} = File.read("12.txt")
    String.split(String.trim(text), "\n")
  end

  def execute_instructions(insts, state \\ %{x: 0, y: 0, dir: 0}) do
    if length(insts) > 0 do
      [inst | remaining] = insts
      nstate = execute(inst, state)
      execute_instructions(remaining, nstate)
    else
      abs(state.x) + abs(state.y)
    end
  end

  def round1() do
    lines = read_instructions()
    IO.puts(execute_instructions(lines))
  end
end

Navigator.round1()
Enter fullscreen mode Exit fullscreen mode
Collapse
 
_bigblind profile image
Frederik 👨‍💻➡️🌐 Creemers

Part 2:

defmodule Navigator do
  def execute(s, state) do
    inst = String.first(s)
    arg = String.to_integer(String.slice(s, 1, String.length(s)-1))
    execute(inst, arg, state)
  end

  def execute("N", dist, state) do
    Map.merge(state, %{wy: state.wy + dist})
  end

  def execute("S", dist, state) do
    Map.merge(state, %{wy: state.wy - dist})
  end

  def execute("E", dist, state) do
    Map.merge(state, %{wx: state.wx + dist})
  end

  def execute("W", dist, state) do
    Map.merge(state, %{wx: state.wx - dist})
  end

  def execute("L", 90, state) do
    Map.merge(state, %{wx: -state.wy, wy: state.wx})
  end

  def execute("R", 90, state) do
    Map.merge(state, %{wx: state.wy, wy: -state.wx})
  end

  def execute("L", 270, state) do execute("R", 90, state) end
  def execute("R", 270, state) do execute("L", 90, state) end
  def execute(d, 180, state) when d in ["L", "R"] do
    Map.merge(state, %{wx: -state.wx, wy: -state.wy})
  end

  def execute("F", dist, state) do
    Map.merge(state, %{x: state.x + state.wx * dist, y: state.y + state.wy * dist})
  end

  def read_instructions() do
    {:ok, text} = File.read("12.txt")
    String.split(String.trim(text), "\n")
  end

  def execute_instructions(insts, state \\ %{x: 0, y: 0, wx: 10, wy: 1}) do
    if length(insts) > 0 do
      [inst | remaining] = insts
      nstate = execute(inst, state)
      execute_instructions(remaining, nstate)
    else
      abs(state.x) + abs(state.y)
    end
  end

  def round2() do
    lines = read_instructions()
    IO.puts(execute_instructions(lines))
  end
end

Navigator.round2()
Enter fullscreen mode Exit fullscreen mode