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()