type tree = Leaf of int * char | Node of int * tree * tree

let weight = function
  | Leaf (w, _) -> w
  | Node (w, _, _) -> w

let rec insert t lst =
  match lst with
  | [] -> [t]
  | h :: rest ->
    if weight t <= weight h then t :: lst
    else h :: insert t rest

let rec build_tree lst =
  match lst with
  | [] -> failwith "empty"
  | [t] -> t
  | a :: b :: rest ->
    let merged = Node (weight a + weight b, a, b) in
    build_tree (insert merged rest)

let rec depth d t =
  match t with
  | Leaf (w, _) -> w * d
  | Node (_, l, r) -> depth (d + 1) l + depth (d + 1) r

;;

let initial = [
  Leaf (5, 'a');
  Leaf (9, 'b');
  Leaf (12, 'c');
  Leaf (13, 'd');
  Leaf (16, 'e');
  Leaf (45, 'f')
] in
let t = build_tree initial in
depth 0 t
