From e057d9f18fd5d0914554c02adc03864cced2ba87 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 10 May 2026 21:47:52 +0000 Subject: [PATCH] ocaml: phase 5.1 next_permutation.ml baseline (5! - 1 = 119 successors) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standard in-place next-permutation (Narayana's algorithm): let next_perm a = let n = Array.length a in let i = ref (n - 2) in while !i >= 0 && a.(!i) >= a.(!i + 1) do i := !i - 1 done; if !i < 0 then false else begin let j = ref (n - 1) in while a.(!j) <= a.(!i) do j := !j - 1 done; swap a.(!i) a.(!j); reverse a (!i + 1) (n - 1); true end Starting from [1;2;3;4;5], next_perm returns true 119 times then false (when reverse-sorted). 5! - 1 = 119. Tests guarded `while … && a.(!i) … do` loops that rely on the iter-242 short-circuit fix. 156 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/next_permutation.ml | 30 ++++++++++++++++++++++++++ plans/ocaml-on-sx.md | 9 ++++++++ 3 files changed, 40 insertions(+) create mode 100644 lib/ocaml/baseline/next_permutation.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index e09b1de9..d1aa3488 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -102,6 +102,7 @@ "module_use.ml": 3, "monotonic.ml": 4, "newton_sqrt.ml": 1414, + "next_permutation.ml": 119, "number_words.ml": 106, "mutable_record.ml": 10, "option_match.ml": 5, diff --git a/lib/ocaml/baseline/next_permutation.ml b/lib/ocaml/baseline/next_permutation.ml new file mode 100644 index 00000000..7cee449e --- /dev/null +++ b/lib/ocaml/baseline/next_permutation.ml @@ -0,0 +1,30 @@ +let next_perm a = + let n = Array.length a in + let i = ref (n - 2) in + while !i >= 0 && a.(!i) >= a.(!i + 1) do + i := !i - 1 + done; + if !i < 0 then false + else begin + let j = ref (n - 1) in + while a.(!j) <= a.(!i) do + j := !j - 1 + done; + let t = a.(!i) in a.(!i) <- a.(!j); a.(!j) <- t; + let lo = ref (!i + 1) and hi = ref (n - 1) in + while !lo < !hi do + let t = a.(!lo) in a.(!lo) <- a.(!hi); a.(!hi) <- t; + lo := !lo + 1; + hi := !hi - 1 + done; + true + end + +;; + +let a = [| 1; 2; 3; 4; 5 |] in +let count = ref 0 in +while next_perm a do + count := !count + 1 +done; +!count diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index f40cd5f2..0646c2ec 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-10 Phase 5.1 — next_permutation.ml baseline (count + permutations of [1;2;3;4;5] via Narayana's algorithm = 119). + Standard in-place algorithm: find largest i with a.(i) < a.(i+1), + largest j > i with a.(j) > a.(i), swap, reverse suffix from i+1. + Returns false when array is the reverse-sorted (final) + permutation. 5! = 120, minus the initial = 119 successful calls. + Tests guarded `while … >= 0 && a.(!i) >= a.(!i + 1) do …` + pattern using the new short-circuit semantics (would loop or + crash without iter-242 fix). 156 baseline programs total. - 2026-05-10 Phase 5.1 — `&&` / `||` short-circuit fix + bfs_grid.ml baseline (BFS shortest path on 5×5 grid with walls, dist 8). The evaluator's `:op` handler was evaluating BOTH sides of `&&`/`||`