From 2726ed9b8ab99118872d58524a40ca87757b4705 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 11 May 2026 02:14:44 +0000 Subject: [PATCH] ocaml: phase 5.1 palindrome_part.ml baseline (min cuts "aabba" = 1) Two-phase palindrome-partition DP for the minimum-cuts variant: Phase 1: is_pal[i][j] palindrome table via length-major fill (single chars, then pairs, then expand inward). Phase 2: cuts[i] = 0 if s[0..i] is itself a palindrome, = min over j of (cuts[j-1] + 1) where s[j..i] is a palindrome. min_cut "aabba" = 1 ("a" | "abba") Tests two sequential 2D DPs sharing the same is_pal matrix, inline begin/end branches inside the length-major fill, mixed bool and int 2D arrays. 181 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/palindrome_part.ml | 35 +++++++++++++++++++++++++++ plans/ocaml-on-sx.md | 10 ++++++++ 3 files changed, 46 insertions(+) create mode 100644 lib/ocaml/baseline/palindrome_part.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 8561668a..35371c95 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -125,6 +125,7 @@ "mutable_record.ml": 10, "option_match.ml": 5, "palindrome.ml": 4, + "palindrome_part.ml": 1, "palindrome_sum.ml": 49500, "paren_depth.ml": 7, "partition.ml": 3025, diff --git a/lib/ocaml/baseline/palindrome_part.ml b/lib/ocaml/baseline/palindrome_part.ml new file mode 100644 index 00000000..0f4b7fb8 --- /dev/null +++ b/lib/ocaml/baseline/palindrome_part.ml @@ -0,0 +1,35 @@ +let min_cut s = + let n = String.length s in + if n <= 1 then 0 + else begin + let is_pal = Array.init n (fun _ -> Array.make n false) in + for i = 0 to n - 1 do is_pal.(i).(i) <- true 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 begin + if len = 2 then is_pal.(i).(j) <- true + else is_pal.(i).(j) <- is_pal.(i + 1).(j - 1) + end + done + done; + let cuts = Array.make n 0 in + for i = 0 to n - 1 do + if is_pal.(0).(i) then cuts.(i) <- 0 + else begin + let best = ref i in + for j = 1 to i do + if is_pal.(j).(i) then begin + let c = cuts.(j - 1) + 1 in + if c < !best then best := c + end + done; + cuts.(i) <- !best + end + done; + cuts.(n - 1) + end + +;; + +min_cut "aabba" diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index f21989ca..6cc60e48 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,16 @@ _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 — palindrome_part.ml baseline (minimum + palindrome-partition cuts in "aabba" = 1). Two-phase DP: + 1) `is_pal.(i).(j)` table via length-major iteration. + 2) `cuts.(i)` = min cuts for prefix s[0..i]; if s[0..i] itself + is a palindrome, 0; else min over j of (cuts.(j-1) + 1) + where s[j..i] is a palindrome. + For "aabba" the optimal partition is "a" | "abba" = 1 cut. + Tests sequential 2D DP passes sharing the same `is_pal` matrix, + inline `if/else begin/end` blocks under length-major fill, mixed + bool and int 2D arrays. 181 baseline programs total. - 2026-05-11 Phase 5.1 — island_count.ml baseline (count 4-connected components of 1-cells in a 6×7 grid = 5). DFS flood from every unvisited 1-cell. Counted islands: