Assume we use a list to represent number reversely, each node is a digit inside the number.
So [1;2;3;4;5]
is the number 54321
Now we want to add up two such lists, e.g., adding [1;2] and [3;4], we get [4;6], which is the number 64.
here is my code:
let add l1 l2 =
let rec add_to up acc = function
| [] -> if up = 1 then 1::acc else acc
| hd::tl ->
let s = hd+up in
if s >= 10 then add_to 1 ((s-10)::acc) tl
else List.rev_append tl (s::acc)
and
add_up up acc = function
| [], [] -> if up = 1 then 1::acc else acc
| l, [] | [], l -> (add_to up [] l) @ acc
| hd1::tl1, hd2::tl2 ->
let s = hd1+hd2+up in
if s >= 10 then add_up 1 ((s-10)::acc) (tl1, tl2)
else add_up 0 (s::acc) (tl1, tl2)
in
List.rev (add_up 0 [] (l1, l2))
The idea is very simple, just add two hds from two lists, and carry 1 to the next if the sum of two hds are bigger or equal with 10.
However, I think my code does not look beautiful.
- we have the redundant part of the logic to solve the carry.
- I have to do
@
on two lists.
Anyone can help me to make it more beautiful?