From 1bde4e834f628f4b7b59004cabdd7bc014896e8f Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 16:56:46 +0000 Subject: [PATCH] ocaml: phase 5.1 stable_unique.ml baseline (Hashtbl dedupe preserving order, 8+38 = 46) Walk input with Hashtbl.mem + Hashtbl.add seen x () (unit-payload turns the table into a set); on first occurrence cons to the result list; reverse at the end: let stable_unique xs = let seen = Hashtbl.create 8 in let result = ref [] in List.iter (fun x -> if not (Hashtbl.mem seen x) then begin Hashtbl.add seen x (); result := x :: !result end ) xs; List.rev !result For [3;1;4;1;5;9;2;6;5;3;5;8;9]: result = [3;1;4;5;9;2;6;8] (input order, dupes dropped) length = 8, sum = 38 total = 46 Tests Hashtbl as a set abstraction (unit-payload), the rev-build idiom, and 'not (Hashtbl.mem seen x)' membership negation. 82 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/stable_unique.ml | 15 +++++++++++++++ plans/ocaml-on-sx.md | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 lib/ocaml/baseline/stable_unique.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index f21e85c2..fe1185bc 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -70,6 +70,7 @@ "run_length.ml": 11, "safe_div.ml": 20, "shuffle.ml": 55, + "stable_unique.ml": 46, "subset_sum.ml": 8, "tic_tac_toe.ml": 1, "word_freq.ml": 8, diff --git a/lib/ocaml/baseline/stable_unique.ml b/lib/ocaml/baseline/stable_unique.ml new file mode 100644 index 00000000..4a108575 --- /dev/null +++ b/lib/ocaml/baseline/stable_unique.ml @@ -0,0 +1,15 @@ +let stable_unique xs = + let seen = Hashtbl.create 8 in + let result = ref [] in + List.iter (fun x -> + if not (Hashtbl.mem seen x) then begin + Hashtbl.add seen x (); + result := x :: !result + end + ) xs; + List.rev !result + +;; + +List.length (stable_unique [3;1;4;1;5;9;2;6;5;3;5;8;9]) ++ List.fold_left (+) 0 (stable_unique [3;1;4;1;5;9;2;6;5;3;5;8;9]) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 8a5be0a8..5f4ddf4a 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,14 @@ _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-09 Phase 5.1 — stable_unique.ml baseline (Hashtbl-tracked + dedupe preserving order, length+sum = 8+38 = 46). Walks input + with `Hashtbl.mem` + `Hashtbl.add seen x ()` (unit-payload to use + the table as a set); on first occurrence cons to the result list, + reverse at the end. For [3;1;4;1;5;9;2;6;5;3;5;8;9] yields + [3;1;4;5;9;2;6;8] — 8 elements summing to 38. Tests Hashtbl as + a set abstraction (ignoring values), and the rev-build idiom. 82 + baseline programs total. - 2026-05-09 Phase 5.1 — run_decode.ml baseline (RLE decode, sum of expansion = 21). Inverse of run_length.ml: takes a list of `(value, count)` tuples, expands each pair via inner `rep` helper,