let bigint_add a b =
  let rec aux a b carry =
    match (a, b) with
    | ([], []) -> if carry = 0 then [] else [carry]
    | (x :: xs, []) ->
      let s = x + carry in
      (s mod 10) :: aux xs [] (s / 10)
    | ([], y :: ys) ->
      let s = y + carry in
      (s mod 10) :: aux [] ys (s / 10)
    | (x :: xs, y :: ys) ->
      let s = x + y + carry in
      (s mod 10) :: aux xs ys (s / 10)
  in
  aux a b 0

;;

let r1 = bigint_add [9;9;9] [1] in
let r2 = bigint_add [5;6;7] [8;9;1] in
let r3 = bigint_add [9;9;9;9;9;9;9;9] [1] in
List.fold_left (+) 0 r1
  + List.fold_left (+) 0 r2
  + List.length r3
