From 6780acd0afda760bb05dd3b612fda398e7347779 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 11 May 2026 01:12:33 +0000 Subject: [PATCH] ocaml: phase 5.1 distinct_subseq.ml baseline ("rabbit" in "rabbbit" = 3) Classic distinct-subsequences 2D DP: dp[i][j] = dp[i-1][j] + (s[i-1] = t[j-1] ? dp[i-1][j-1] : 0) dp[i][0] = 1 (empty t is a subseq of any prefix of s) count_subseq "rabbbit" "rabbit" = 3 The three witnesses correspond to which 'b' in "rabbbit" is dropped (positions 2, 3, or 4 zero-indexed of the run of bs). Complements subseq_check.ml (just tests presence); this one counts distinct embeddings. Tests 2D DP with Array.init n (fun _ -> Array.make m 0), base row initialization, mixed string + array indexing. 175 baseline programs total. --- lib/ocaml/baseline/distinct_subseq.ml | 20 ++++++++++++++++++++ lib/ocaml/baseline/expected.json | 1 + plans/ocaml-on-sx.md | 9 +++++++++ 3 files changed, 30 insertions(+) create mode 100644 lib/ocaml/baseline/distinct_subseq.ml diff --git a/lib/ocaml/baseline/distinct_subseq.ml b/lib/ocaml/baseline/distinct_subseq.ml new file mode 100644 index 00000000..f5231c45 --- /dev/null +++ b/lib/ocaml/baseline/distinct_subseq.ml @@ -0,0 +1,20 @@ +let count_subseq s t = + let m = String.length s in + let n = String.length t in + let dp = Array.init (m + 1) (fun _ -> Array.make (n + 1) 0) in + for i = 0 to m do + dp.(i).(0) <- 1 + done; + for i = 1 to m do + for j = 1 to n do + if s.[i - 1] = t.[j - 1] then + dp.(i).(j) <- dp.(i - 1).(j) + dp.(i - 1).(j - 1) + else + dp.(i).(j) <- dp.(i - 1).(j) + done + done; + dp.(m).(n) + +;; + +count_subseq "rabbbit" "rabbit" diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index bf25a668..e5b67380 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -34,6 +34,7 @@ "csv.ml": 10, "egg_drop.ml": 8, "dijkstra.ml": 7, + "distinct_subseq.ml": 3, "exception_handle.ml": 4, "exception_user.ml": 26, "euler1.ml": 233168, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index ffadc782..eaeecb98 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-11 Phase 5.1 — distinct_subseq.ml baseline (count + distinct subsequences of "rabbbit" that equal "rabbit" = 3). + Classic 2D DP: dp[i][j] = dp[i-1][j] + (s[i-1]=t[j-1] ? dp[i-1][j-1] + : 0). Three witnesses correspond to which `b` in "rabbbit" is + dropped: positions 2, 3, or 4 (0-indexed of the three b's). + Complements existing subseq_check.ml which just tests presence. + Tests 2D DP with `Array.init … (fun _ -> Array.make …)`, edge- + case base row dp[i][0]=1 (empty t is a subseq of any prefix). + 175 baseline programs total. - 2026-05-11 Phase 5.1 — bracket_match.ml baseline (multi-bracket parenthesis matching over 9 test strings, 5 balanced). Stack- based scan: push openers `( [ {`, pop and pair-check closers.