From f9371e7d222f92522636027beb4693ed18cca494 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 11 May 2026 01:32:41 +0000 Subject: [PATCH] ocaml: phase 5.1 lps_dp.ml baseline (LPS "BBABCBCAB" = 7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standard O(n^2) length-major DP for longest palindromic subsequence: dp[i][j] = dp[i+1][j-1] + 2 if s[i] = s[j] = max(dp[i+1][j], dp[i][j-1]) otherwise lps "BBABCBCAB" = 7 (witness "BABCBAB" etc.) Complementary to manacher.ml (longest palindromic *substring*, also length 7 on that input by coincidence) — this is the subsequence variant which doesn't require contiguity. Tests length-major fill order, inline if for the length-2 base case, double-nested for with derived j = i + len - 1. 177 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/lps_dp.ml | 21 +++++++++++++++++++++ plans/ocaml-on-sx.md | 9 +++++++++ 3 files changed, 31 insertions(+) create mode 100644 lib/ocaml/baseline/lps_dp.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index a1dc3edf..3fc5f364 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -85,6 +85,7 @@ "floyd_warshall.ml": 9, "lis.ml": 6, "list_ops.ml": 30, + "lps_dp.ml": 7, "lru_cache.ml": 499, "luhn.ml": 2, "magic_square.ml": 65, diff --git a/lib/ocaml/baseline/lps_dp.ml b/lib/ocaml/baseline/lps_dp.ml new file mode 100644 index 00000000..6d7727c4 --- /dev/null +++ b/lib/ocaml/baseline/lps_dp.ml @@ -0,0 +1,21 @@ +let lps s = + let n = String.length s in + let dp = Array.init n (fun _ -> Array.make n 0) in + for i = 0 to n - 1 do dp.(i).(i) <- 1 done; + for len = 2 to n do + for i = 0 to n - len do + let j = i + len - 1 in + if s.[i] = s.[j] then + dp.(i).(j) <- (if len = 2 then 2 else dp.(i + 1).(j - 1) + 2) + else begin + let a = dp.(i + 1).(j) in + let b = dp.(i).(j - 1) in + dp.(i).(j) <- if a > b then a else b + end + done + done; + dp.(0).(n - 1) + +;; + +lps "BBABCBCAB" diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 83d4d614..28ae44c5 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 — lps_dp.ml baseline (longest palindromic + subsequence in "BBABCBCAB" = 7). Classic 2D O(n²) DP over + substring lengths: dp[i][j] = dp[i+1][j-1] + 2 when s[i]=s[j], + else max(dp[i+1][j], dp[i][j-1]). Witness LPS is "BABCBAB" (or + "BACBCAB" etc.) of length 7. Complementary to manacher.ml + (substring, length 7) — this is the subsequence variant. + Tests length-major fill order, mixed strict/inline if for + `len = 2` base case, double-nested for with derived j. 177 + baseline programs total. - 2026-05-11 Phase 5.1 — bs_bounds.ml baseline (lower_bound / upper_bound binary search; counts of {3,2,5,9,4} in [1;2;2;3;3;3;5;7;9] encoded as 3211). Standard half-open