From 8fab20c8bcf5b568ab5aac1801915d4a7ac3d2c7 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 8 May 2026 19:57:09 +0000 Subject: [PATCH] ocaml: phase 5.1 anagrams.ml baseline (18/18 pass) Group anagrams by canonical (sorted-chars) key using Hashtbl + List.sort. Demonstrates char-by-char traversal via String.get + for-loop + ref accumulator + Hashtbl as a multi-valued counter. --- lib/ocaml/baseline/anagrams.ml | 26 ++++++++++++++++++++++++++ lib/ocaml/baseline/expected.json | 1 + plans/ocaml-on-sx.md | 3 +++ 3 files changed, 30 insertions(+) create mode 100644 lib/ocaml/baseline/anagrams.ml diff --git a/lib/ocaml/baseline/anagrams.ml b/lib/ocaml/baseline/anagrams.ml new file mode 100644 index 00000000..a1f4666a --- /dev/null +++ b/lib/ocaml/baseline/anagrams.ml @@ -0,0 +1,26 @@ +(* Baseline: count anagram groups using Hashtbl + sort *) + +(* Sort the chars in a string to get its anagram-equivalence key *) +let canonical s = + let n = String.length s in + let chars = ref [] in + for i = 0 to n - 1 do + chars := (String.get s i) :: !chars + done ; + let sorted = List.sort compare !chars in + String.concat "" sorted +;; + +let count_groups words = + let counts = Hashtbl.create 16 in + List.iter + (fun w -> + let k = canonical w in + match Hashtbl.find_opt counts k with + | None -> Hashtbl.add counts k 1 + | Some n -> Hashtbl.replace counts k (n + 1)) + words ; + Hashtbl.length counts +;; + +count_groups ["eat"; "tea"; "tan"; "ate"; "nat"; "bat"] diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 27ecf27b..c22a2ed9 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -1,4 +1,5 @@ { + "anagrams.ml": 3, "btree.ml": 39, "calc.ml": 13, "closures.ml": 315, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 879a0226..b1fa4cb7 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,9 @@ _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-08 Phase 5.1 — anagrams.ml baseline (18/18 pass). Counts + anagram-equivalence groups via Hashtbl + List.sort + String.get + + for-loop. `["eat";"tea";"tan";"ate";"nat";"bat"]` → 3 groups. - 2026-05-08 Phase 5.1 — lambda_calc.ml baseline (17/17 pass). Untyped lambda calculus interpreter using two ADTs (`type term = Var | Abs | App | Num`, `type value = VNum | VClos`), an env as `(string * value)