let max_digit n arr =
  let m = ref arr.(0) in
  for i = 1 to n - 1 do
    if arr.(i) > !m then m := arr.(i)
  done;
  let d = ref 0 in
  let x = ref !m in
  while !x > 0 do
    d := !d + 1;
    x := !x / 10
  done;
  !d

let radix_sort arr =
  let n = Array.length arr in
  let maxd = max_digit n arr in
  let exp = ref 1 in
  for _ = 1 to maxd do
    let buckets = Array.init 10 (fun _ -> ref []) in
    for i = 0 to n - 1 do
      let digit = (arr.(i) / !exp) mod 10 in
      let b = buckets.(digit) in
      b := arr.(i) :: !b
    done;
    let k = ref 0 in
    for d = 0 to 9 do
      let xs = List.rev !(buckets.(d)) in
      List.iter (fun v ->
        arr.(!k) <- v;
        k := !k + 1
      ) xs
    done;
    exp := !exp * 10
  done

;;

let a = [| 170; 45; 75; 90; 802; 24; 2; 66 |] in
radix_sort a;
a.(0) + a.(7) * 1000
