let parent i = (i - 1) / 2
let lchild i = 2 * i + 1
let rchild i = 2 * i + 2

let swap a i j =
  let t = a.(i) in
  a.(i) <- a.(j);
  a.(j) <- t

let rec sift_up a i =
  if i > 0 && a.(parent i) > a.(i) then begin
    swap a i (parent i);
    sift_up a (parent i)
  end

let rec sift_down a n i =
  let l = lchild i and r = rchild i in
  let smallest = ref i in
  if l < n && a.(l) < a.(!smallest) then smallest := l;
  if r < n && a.(r) < a.(!smallest) then smallest := r;
  if !smallest <> i then begin
    swap a i !smallest;
    sift_down a n !smallest
  end

let push a size x =
  a.(!size) <- x;
  size := !size + 1;
  sift_up a (!size - 1)

let pop a size =
  let m = a.(0) in
  size := !size - 1;
  a.(0) <- a.(!size);
  sift_down a !size 0;
  m

;;

let a = Array.make 20 0 in
let s = ref 0 in
List.iter (fun x -> push a s x) [9; 4; 7; 1; 8; 3; 5; 2; 6];
let total = ref 0 in
for _ = 1 to 9 do
  total := !total * 10 + pop a s
done;
!total
