From 74d8ade089753f44d02735468d5cb0af6140fa3b Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 10 May 2026 05:01:08 +0000 Subject: [PATCH] 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. --- lib/ocaml/baseline/count_inversions.ml | 42 ++++++++++++++++++++++++++ lib/ocaml/baseline/expected.json | 1 + plans/ocaml-on-sx.md | 7 +++++ 3 files changed, 50 insertions(+) create mode 100644 lib/ocaml/baseline/count_inversions.ml diff --git a/lib/ocaml/baseline/count_inversions.ml b/lib/ocaml/baseline/count_inversions.ml new file mode 100644 index 00000000..8daae61b --- /dev/null +++ b/lib/ocaml/baseline/count_inversions.ml @@ -0,0 +1,42 @@ +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|] diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 13c5866c..ea5be3fe 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -24,6 +24,7 @@ "closures.ml": 315, "coin_change.ml": 6, "count_change.ml": 406, + "count_inversions.ml": 12, "csv.ml": 10, "dijkstra.ml": 7, "exception_handle.ml": 4, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index d5e6dca9..5f4211cc 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,13 @@ _Newest first._ binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree`) with insert + in-order traversal. Tests parametric ADT, recursive match, List.append, List.fold_left. +- 2026-05-10 Phase 5.1 — count_inversions.ml baseline (count + inversions of [|8;4;2;1;3;5;7;6|] = 12, via merge-sort). Modified + merge sort: when right element is taken, accumulate `mid - i + 1` + inversions for the remaining left half. Tests `let rec merge ... + and sort ...` mutually recursive bindings, complex while + ref + + array mutation, in-place sort with auxiliary array. + 145 baseline programs total. - 2026-05-10 Phase 5.1 — topo_sort.ml baseline (Kahn's algorithm topological sort of a 6-node DAG → all 6 vertices ordered). Standard BFS approach: compute in-degrees, seed queue with zero-