Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Add Two Numbers

elixir/2-add-wwo-numbers.livemd

Add Two Numbers

S1

defmodule ListNode do
  @type t :: %__MODULE__{val: integer, next: ListNode.t() | nil}
  defstruct val: 0, next: nil
end

defmodule Solution do
  @spec add_two_numbers(l1 :: ListNode.t() | nil, l2 :: ListNode.t() | nil) :: ListNode.t() | nil
  def add_two_numbers(l1, l2) do
    add_two_numbers(l1, l2, 0)
  end

  def add_two_numbers(nil, nil, 0) do
    nil
  end

  def add_two_numbers(nil, nil, 1) do
    %ListNode{val: 1}
  end

  def add_two_numbers(l1, nil, carry) do
    add_two_numbers(l1, %ListNode{val: 0}, carry)
  end

  def add_two_numbers(nil, l2, carry) do
    add_two_numbers(%ListNode{val: 0}, l2, carry)
  end

  def add_two_numbers(l1, l2, carry) do
    val = l1.val + l2.val + carry

    %ListNode{
      val: rem(val, 10),
      next: add_two_numbers(l1.next, l2.next, div(val, 10))
    }
  end
end
ExUnit.start(autorun: false)

defmodule Test do
  use ExUnit.Case

  def new(list) do
    list
    |> Enum.reverse()
    |> Enum.reduce(nil, fn val, node ->
      %ListNode{val: val, next: node}
    end)
  end

  test nil do
    assert Solution.add_two_numbers(new([1, 2, 3, 4]), new([0, 0, 0, 0])) == new([1, 2, 3, 4])
    assert Solution.add_two_numbers(new([1, 2, 3, 4]), new([1, 2, 3, 4])) == new([2, 4, 6, 8])
    assert Solution.add_two_numbers(new([0]), new([0])) == new([0])
    assert Solution.add_two_numbers(new([2, 4, 3]), new([5, 6, 4])) == new([7, 0, 8])

    assert Solution.add_two_numbers(
             new([9, 9, 9, 9, 9, 9, 9]),
             new([9, 9, 9, 9])
           ) == new([8, 9, 9, 9, 0, 0, 0, 1])
  end
end

ExUnit.run()