My solution, simple but honest:
Part 1:
defmodule Submarine do
def calc_position(list) do
forward_sum = sum_movement(list, "forward")
up_sum = sum_movement(list, "up")
down_sum = sum_movement(list, "down")
depth = down_sum - up_sum
forward_sum * depth
end
defp sum_movement(movs, type) do
movs
|> Enum.filter(fn [k,_v] -> k == type end)
|> Enum.map(fn [_k,v] -> String.to_integer(v) end)
|> Enum.reduce(fn x, acc -> x + acc end)
end
end
input
|> String.split(" ")
|> Enum.chunk_every(2)
|> Submarine.calc_position
Part 2:
defmodule Submarine2 do
def calc_position(list) do
_calc(list, 0, 0, 0)
end
defp _calc([head | tail], aim, horizontal, depth) do
[key, value] = head
cond do
key == "forward" ->
new_horizontal = horizontal + String.to_integer(value)
_calc(tail, aim, new_horizontal, calc_depth(depth, aim, String.to_integer(value)) )
key == "down" ->
_calc(tail, aim + String.to_integer(value), horizontal, depth)
key == "up" ->
_calc(tail, aim - String.to_integer(value), horizontal, depth)
end
end
defp _calc([], _, horizontal, depth) do
horizontal * depth
end
defp calc_depth(depth, aim, forward_value) do
depth + (aim * forward_value)
end
end
input
|> String.split(" ")
|> Enum.chunk_every(2)
|> Submarine2.calc_position