ocaml: phase 5.1 bag.ml baseline + String.equal/compare/cat/empty (+3 tests, 579 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s

bag.ml: split a sentence on spaces, count each word in a Hashtbl,
return the maximum count via Hashtbl.fold.

  count_words 'the quick brown fox jumps over the lazy dog the fox'
  -> Hashtbl with 'the' = 3 as the max
  -> 3

Exercises String.split_on_char + Hashtbl.find_opt/replace +
Hashtbl.fold (k v acc -> ...). Together with frequency.ml from
iter 84 we now have two Hashtbl-counting baselines exercising
slightly different idioms. 29 baseline programs total.

String additions:
  equal a b      = a = b
  compare a b    = -1 / 0 / 1 via host < / >
  cat a b        = a ^ b
  empty          = '' (constant)
This commit is contained in:
2026-05-09 06:15:03 +00:00
parent 7ca5bfbb70
commit ddd1e40d00
5 changed files with 45 additions and 0 deletions

18
lib/ocaml/baseline/bag.ml Normal file
View File

@@ -0,0 +1,18 @@
let count_words text =
let words = String.split_on_char ' ' text in
let counts = Hashtbl.create 8 in
List.iter (fun w ->
let n = match Hashtbl.find_opt counts w with
| Some n -> n + 1
| None -> 1
in
Hashtbl.replace counts w n
) words;
counts
let max_count counts =
Hashtbl.fold (fun _ v acc -> if v > acc then v else acc) counts 0
;;
max_count (count_words "the quick brown fox jumps over the lazy dog the fox")

View File

@@ -1,5 +1,6 @@
{
"anagrams.ml": 3,
"bag.ml": 3,
"bfs.ml": 6,
"btree.ml": 39,
"brainfuck.ml": 75,

View File

@@ -447,6 +447,11 @@
| h :: t -> aux t (acc ^ h)
in
aux xs \"\"
let equal a b = a = b
let compare a b =
if a < b then -1 else if a > b then 1 else 0
let cat a b = a ^ b
let empty = \"\"
end ;;
module Bytes = struct

View File

@@ -1440,6 +1440,14 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 5193)
(eval "(ocaml-run \"Seq.fold_left (+) 0 (Seq.unfold (fun n -> if n > 4 then None else Some (n, n + 1)) 1)\")")
;; ── String.equal / compare / cat ─────────────────────────────
(epoch 5200)
(eval "(ocaml-run \"String.equal \\\"abc\\\" \\\"abc\\\"\")")
(epoch 5201)
(eval "(ocaml-run \"String.compare \\\"banana\\\" \\\"apple\\\"\")")
(epoch 5202)
(eval "(ocaml-run \"String.cat \\\"hello \\\" \\\"world\\\"\")")
EPOCHS
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
@@ -2290,6 +2298,11 @@ check 5191 "Seq filter evens" '5'
check 5192 "Seq init 5 i*2" '20'
check 5193 "Seq unfold 1..4 sum" '10'
# ── String.equal / compare / cat ────────────────────────────────
check 5200 "String.equal abc abc" 'true'
check 5201 "String.compare banana apple" '1'
check 5202 "String.cat hello world" '"hello world"'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"

View File

@@ -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 — bag.ml baseline + String.equal/compare/cat/
empty (+3 tests, 579 total). bag.ml: split a sentence on spaces,
count word frequency in a Hashtbl, return the maximum count.
Sentence "the quick brown fox jumps over the lazy dog the fox" has
"the"×3 as the most frequent → 3. Exercises String.split_on_char +
Hashtbl.find_opt/replace + Hashtbl.fold over (k, v) tuples. 29
baseline programs total. String additions: equal, compare (via host
`<`/`>`), cat (alias of `^`), empty.
- 2026-05-09 Phase 5.1 — fraction.ml baseline (rational arithmetic
via record + gcd canonicalization). Defines `type frac = { num;
den }`, `make` that reduces via gcd and forces den > 0, `add` and