Files
rose-ash/lib/ocaml/baseline/count_inversions.ml
giles 74d8ade089
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
ocaml: phase 5.1 count_inversions.ml baseline (12 inversions via merge sort)
Modified merge sort that counts inversions during the merge step:
when an element from the right half is selected, the remaining
elements of the left half (mid - i + 1) all form inversions with
that right element.

  count_inv [|8; 4; 2; 1; 3; 5; 7; 6|] = 12

Inversions of [8;4;2;1;3;5;7;6]:
  with 8: (8,4)(8,2)(8,1)(8,3)(8,5)(8,7)(8,6) = 7
  with 4: (4,2)(4,1)(4,3) = 3
  with 2: (2,1) = 1
  with 7: (7,6) = 1
                                        total = 12

Tests: let rec ... and ... mutual recursion, while + ref + array
mutation, in-place sort with auxiliary scratch array.

145 baseline programs total.
2026-05-10 05:01:08 +00:00

43 lines
941 B
OCaml

let count_inv arr =
let n = Array.length arr in
let temp = Array.make n 0 in
let count = ref 0 in
let rec merge lo mid hi =
let i = ref lo and j = ref (mid + 1) and k = ref lo in
while !i <= mid && !j <= hi do
if arr.(!i) <= arr.(!j) then begin
temp.(!k) <- arr.(!i);
i := !i + 1
end else begin
temp.(!k) <- arr.(!j);
count := !count + (mid - !i + 1);
j := !j + 1
end;
k := !k + 1
done;
while !i <= mid do
temp.(!k) <- arr.(!i);
i := !i + 1; k := !k + 1
done;
while !j <= hi do
temp.(!k) <- arr.(!j);
j := !j + 1; k := !k + 1
done;
for x = lo to hi do
arr.(x) <- temp.(x)
done
and sort lo hi =
if lo < hi then begin
let mid = (lo + hi) / 2 in
sort lo mid;
sort (mid + 1) hi;
merge lo mid hi
end
in
sort 0 (n - 1);
!count
;;
count_inv [|8; 4; 2; 1; 3; 5; 7; 6|]