From bcb7db2ea469207babad3729b78f73726336648f Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 10 May 2026 22:17:40 +0000 Subject: [PATCH] ocaml: phase 5.1 radix_sort.ml baseline (LSD radix sort, sentinel 802002) LSD radix sort over base 10 digits. Per pass: - 10 bucket-refs created via Array.init 10 (fun _ -> ref []) (each closure call yields a distinct list cell) - scan array, append each value to its digit's bucket - flatten buckets back to the array in order Input [170;45;75;90;802;24;2;66] Output [2;24;45;66;75;90;170;802] Sentinel: a.(0) + a.(7)*1000 = 2 + 802*1000 = 802002. Tests array-of-refs with !buckets.(d) deref, list-mode bucket sort within in-place array sort, unused for-loop var (`for _ = 1 to maxd`). 159 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/radix_sort.ml | 40 ++++++++++++++++++++++++++++++++ plans/ocaml-on-sx.md | 9 +++++++ 3 files changed, 50 insertions(+) create mode 100644 lib/ocaml/baseline/radix_sort.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index e3b5f06a..f980e5bf 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -127,6 +127,7 @@ "queens.ml": 2, "quickselect.ml": 5, "quicksort.ml": 44, + "radix_sort.ml": 802002, "roman.ml": 44, "rolling_hash.ml": 6, "reverse_int.ml": 54329, diff --git a/lib/ocaml/baseline/radix_sort.ml b/lib/ocaml/baseline/radix_sort.ml new file mode 100644 index 00000000..82353d35 --- /dev/null +++ b/lib/ocaml/baseline/radix_sort.ml @@ -0,0 +1,40 @@ +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 diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index ed2dd5ae..253ec778 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,15 @@ _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 — radix_sort.ml baseline (LSD radix sort, + fingerprint a.(0) + a.(7)*1000 = 802002). 8-element array + [170;45;75;90;802;24;2;66] sorts to [2;24;45;66;75;90;170;802]. + Sentinel encoding 2 + 802*1000 = 802002. Uses `Array.init 10 + (fun _ -> ref [])` to allocate 10 fresh per-digit bucket cells + per pass (each closure call yields a distinct ref). Tests + array-of-refs with `!buckets.(d)` deref pattern, list-mode + bucket sort within in-place array sort, `for _ = 1 to maxd` + unused loop variable. 159 baseline programs total. - 2026-05-10 Phase 5.1 — coin_min.ml baseline (minimum-coin change for 67¢ with US denominations = 6 coins). DP with -1 sentinel for unreachable values: `dp.(i) := min over coins c of dp.(i-c)+1