Classic O(n) greedy gas-station algorithm:
walk once, tracking
total = sum of (gas[i] - cost[i]) -- if negative, no answer
curr = running tank since start -- on negative, advance
start past i+1 and reset
if total < 0 then -1 else start
For gas = [1;2;3;4;5], cost = [3;4;5;1;2], unique start = 3.
Tests `total` + `curr` parallel accumulators, reset-on-failure
pattern.
202 baseline programs total.
Greedy BFS-frontier style — track the farthest reach within the
current jump's reachable range, and bump the jump counter when i
runs into the current frontier:
while !i < n - 1 do
farthest := max(farthest, i + arr.(i));
if !i = !cur_end then begin
jumps := !jumps + 1;
cur_end := !farthest
end;
i := !i + 1
done
For [2; 3; 1; 1; 2; 4; 2; 0; 1; 1] (n = 10), the optimal jump
sequence 0 -> 1 -> 4 -> 5 -> 9 uses 4 jumps.
Tests greedy-with-frontier pattern, three parallel refs
(jumps, cur_end, farthest), mixed for-style index loop using ref.
201 baseline programs total.
Pascal-recursion combination enumerator:
let rec choose k xs =
if k = 0 then [[]]
else match xs with
| [] -> []
| h :: rest ->
List.map (fun c -> h :: c) (choose (k - 1) rest)
@ choose k rest
C(9, 4) = |choose 4 [1; ...; 9]| = 126
Tests pure-functional enumeration with List.map + closure over h,
@ append, [] | h :: rest pattern match on shrinking input.
200 baseline programs total -- milestone.
Monotonic decreasing stack — for each day i, pop entries from
the stack whose temperature is strictly less than today's; their
answer is (i - popped_index).
temps = [73; 74; 75; 71; 69; 72; 76; 73]
answer = [ 1; 1; 4; 2; 1; 1; 0; 0]
sum = 10
Complementary to next_greater.ml (iter 256) — same monotonic-stack
skeleton but stores the distance to the next greater element
rather than its value.
Tests `match !stack with | top :: rest when …` pattern with
guard inside a while-cont-flag loop.
198 baseline programs total.
DP recurrence for popcount that avoids host bitwise operations:
result[i] = result[i / 2] + (i mod 2)
Drops the low bit (i / 2 stands in for i lsr 1) and adds it back
if it was 1 (i mod 2 stands in for i land 1).
sum over 0..100 of popcount(i) = 319
Tests pure-arithmetic popcount, accumulating ref + DP array,
classic look-back to half-index pattern.
197 baseline programs total.
Binary search in a rotated sorted array. Standard sorted-half
test at each step:
if arr.(lo) <= arr.(mid) then
left half [lo, mid] is sorted -> check whether target is in it
else
right half [mid, hi] is sorted -> check whether target is in it
For [4; 5; 6; 7; 0; 1; 2]:
search 0 -> index 4
search 7 -> index 3
search 3 -> -1 (absent)
Encoded fingerprint: 4 + 3*10 + (-1)*100 = -66.
First baseline returning a negative top-level value; the runner
uses literal grep -qF so leading minus parses fine.
196 baseline programs total.
Task-scheduler closed-form min total intervals:
m = max letter frequency
k = number of letters tied at frequency m
answer = max((m - 1) * (n + 1) + k, total_tasks)
For "AAABBC" with cooldown n = 2:
freq A = 3, freq B = 2, freq C = 1 -> m = 3, k = 1
formula = (3 - 1) * (2 + 1) + 1 = 7
total tasks = 6
answer = 7
Witness schedule: A, B, C, A, B, idle, A.
Tests String.iter with side-effecting count update via
Char.code arithmetic, fixed-size 26-bucket histogram.
195 baseline programs total.
Classic two-pointer / sliding window: expand right, then shrink
left while the window still satisfies the >= constraint, recording
the smallest valid length.
for r = 0 to n - 1 do
sum := !sum + arr.(r);
while !sum >= target do
... record (r - !l + 1) if smaller ...
sum := !sum - arr.(!l);
l := !l + 1
done
done
For [2; 3; 1; 2; 4; 3], target 7 -> window [4, 3] of length 2.
Sentinel n+1 marks "not found"; final guard reduces to 0.
Tests for + inner while shrinking loop, ref-tracked sum updated
on both expansion and contraction.
194 baseline programs total.
Sweep-line algorithm via separately-sorted starts / ends arrays:
while i < n do
if starts[i] < ends[j] then begin busy++; rooms = max; i++ end
else begin busy--; j++ end
done
intervals: (0,30) (5,10) (15,20) (10,25) (5,12)
(20,35) (0,5) (8,18)
At time 8, meetings (0,30), (5,10), (5,12), (8,18) are all active
simultaneously -> answer = 4.
Tests local helper bound via let (`let bubble a = ...`) for
in-place sort, dual-pointer sweep on parallel ordered event streams.
193 baseline programs total.
Two-pass partition DP for max profit with at most 2 transactions:
left[i] = max single-trans profit in prices[0..i]
(forward scan tracking running min)
right[i] = max single-trans profit in prices[i..n-1]
(backward scan tracking running max)
answer = max over i of (left[i] + right[i])
For [3; 3; 5; 0; 0; 3; 1; 4]:
optimal partition i = 2:
left[2] = sell@5 after buy@3 = 2
right[2] = sell@4 after buy@0 in [2..7] = 4
total = 6
Tests parallel forward + backward passes on parallel DP arrays,
mixed ref + array state, for downto + for ascending scans on
the same data.
190 baseline programs total.
Expand-around-center linear-time palindrome counting:
for c = 0 to 2*n - 2 do
let l = ref (c / 2) in
let r = ref ((c + 1) / 2) in
while !l >= 0 && !r < n && s.[!l] = s.[!r] do
count := !count + 1; l := !l - 1; r := !r + 1
done
done
The 2n-1 centers cover both odd (c even -> l = r) and even
(c odd -> l = r - 1) palindromes.
For "aabaa":
5 singletons + 2 "aa" + 1 "aba" + 1 "aabaa" = 9
Complements lps_dp.ml (longest subsequence) and manacher.ml
(longest substring); this one *counts* all palindromic substrings.
187 baseline programs total.
Floyd's cycle detection on a numeric function f(x) = (2x + 5) mod 17.
Three phases:
Phase 1: advance slow/fast until collision inside the cycle
(fast double-steps, slow single-steps)
Phase 2: restart slow from x0; advance both by 1 until they
meet — count is mu (length of tail before cycle)
Phase 3: advance fast around cycle once until it meets slow
— count is lam (cycle length)
For x0 = 1, the orbit visits 1, 7, 2, 9, 6, 0, 5, 15 then returns
to 1 — pure cycle of length 8, mu = 0, lam = 8. Encoded as
mu*100 + lam = 8.
Tests three sequential while loops sharing ref state,
double-step `fast := f (f !fast)`, meeting-condition flag.
185 baseline programs total.
Two-pointer merge advancing the smaller-head pointer k times,
without materializing the merged array:
while !count < k do
let pick_a =
if !i = m then false (* a exhausted, take from b *)
else if !j = n then true (* b exhausted, take from a *)
else a.(!i) <= b.(!j)
in
if pick_a then ... else ...;
count := !count + 1
done
For a = [1;3;5;7;9;11;13], b = [2;4;6;8;10;12]:
merged order: 1,2,3,4,5,6,7,8,9,10,11,12,13
8th element = 8.
Tests nested if/else if/else flowing into a bool, dual-ref
two-pointer loop, separate count counter for k-th constraint.
184 baseline programs total.
Recursive permutation generator via fold-pick-recurse:
let rec permutations xs = match xs with
| [] -> [[]]
| _ ->
List.fold_left (fun acc x ->
let rest = List.filter (fun y -> y <> x) xs in
let subs = permutations rest in
acc @ List.map (fun p -> x :: p) subs
) [] xs
For permutations of [1; 2; 3; 4] (24 total), count those whose
first element is less than the last:
match p with
| [a; _; _; b] when a < b -> count := !count + 1
| _ -> ()
By symmetry, exactly half satisfy a < b = 12.
Tests List.filter, recursive fold with append, fixed-length
list pattern [a; _; _; b] with multiple wildcards + when guard.
183 baseline programs total.
Recursive regex matcher with Leetcode-style semantics:
. matches any single character
<c>* matches zero or more of <c>
let rec is_match s i p j =
if j = String.length p then i = String.length s
else
let first = i < String.length s
&& (p.[j] = '.' || p.[j] = s.[i])
in
if j + 1 < String.length p && p.[j+1] = '*' then
is_match s i p (j + 2) (* skip * group *)
|| (first && is_match s (i + 1) p j) (* consume one *)
else
first && is_match s (i + 1) p (j + 1)
Patterns vs texts:
.a.b | aabb axb "" abcd abc aaabbbc x -> 1 match
a.*b | aabb axb "" abcd abc aaabbbc x -> 2 matches
x* | aabb axb "" abcd abc aaabbbc x -> 2 matches
a*b*c | aabb axb "" abcd abc aaabbbc x -> 2 matches
total = 7
Complements wildcard_match.ml which uses LIKE-style * / ?.
182 baseline programs total.
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.
Classic word-break DP — for each position i, check whether any
dictionary word ends at i with a prior reachable position:
dp[i] = exists w in dict with wl <= i and
dp[i - wl] && s.sub (i - wl) wl = w
Dictionary: apple, pen, pine, pineapple, cats, cat, and, sand, dog
Inputs:
applepenapple yes (apple pen apple)
pineapplepenapple yes (pineapple pen apple)
catsanddog yes (cats and dog)
catsandog no (no segmentation reaches the end)
applesand yes (apple sand)
Tests bool-typed Array, String.sub primitive, nested List.iter
over the dict inside for-loop over end positions, closure capture
of the outer dp.
179 baseline programs total.
Linear-time stack algorithm for largest rectangle in histogram:
for i = 0 to n do
let h = if i = n then 0 else heights.(i) in
while top-of-stack's height > h do
pop the top, compute its max-width rectangle:
width = (no-stack ? i : i - prev_top - 1)
area = height * width
update best
done;
if i < n then push i
done
Sentinel pass at i=n with h=0 flushes the remaining stack.
For [2; 1; 5; 6; 2; 3], bars at indices 2 (h=5) and 3 (h=6) form
a width-2 rectangle of height 5 = 10.
Tests guarded patterns with `when` inside while-cont-flag, nested
`match !stack with | [] -> i | t :: _ -> i - t - 1` for width
computation.
178 baseline programs total.
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.
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.
Stack-based multi-bracket parenthesis matching for ( [ { ) ] }.
Non-bracket chars are skipped (treated as content).
Tests:
() yes
[{()}] yes
({[}]) no (mismatched closer)
"" yes
(( no (unclosed)
()[](){} yes
(a(b)c) yes (a/b/c skipped)
(() no
]) no
5 balanced
Body uses begin/end-wrapped match inside while:
else if c = ')' || c = ']' || c = '}' then begin
match !stack with
| [] -> ok := false
| top :: rest ->
let pair =
(c = ')' && top = '(') ||
(c = ']' && top = '[') ||
(c = '}' && top = '{')
in
if pair then stack := rest else ok := false
end
Tests side-effecting match arms inside while body, ref-of-list as
stack, multi-char pairing dispatch.
174 baseline programs total.
Recursive wildcard matcher:
let rec is_match s i p j =
if j = String.length p then i = String.length s
else if p.[j] = '*' then
is_match s i p (j + 1) (* * matches empty *)
|| (i < String.length s && is_match s (i + 1) p j) (* * eats char *)
else
i < String.length s
&& (p.[j] = '?' || p.[j] = s.[i])
&& is_match s (i + 1) p (j + 1)
Patterns vs texts:
a*b | aaab abc abxyz xy xyz axby -> 1 match
?b*c | aaab abc abxyz xy xyz axby -> 1 match
*x*y* | aaab abc abxyz xy xyz axby -> 4 matches
total = 6
Tests deeply nested short-circuit && / ||, char equality on
pattern bytes, doubly-nested List.iter cross product.
173 baseline programs total.
Recursive powerset construction by doubling:
let rec gen xs = match xs with
| [] -> [[]]
| h :: rest ->
let sub = gen rest in
sub @ List.map (fun s -> h :: s) sub
Enumerates all 2^10 = 1024 subsets, filters by sum:
count = |{ S ⊆ {1..10} | Σ S = 15 }| = 20
Examples: {1,2,3,4,5}, {2,3,4,6}, {1,4,10}, {7,8}, {6,9}, ...
Tests recursive subset construction via List.map + closures,
pattern matching with h :: rest, List.fold_left (+) 0 sum reduce,
exhaustive O(2^n * n) traversal.
172 baseline programs total.
Real OCaml accepts `match e1, e2 with | p1, p2 -> …` without
surrounding parens. parse-pattern previously stopped at the cons
layer (`p :: rest`) and treated a trailing `,` as a separator
the outer caller couldn't handle, surfacing as
"expected op -> got op ,".
Fix: `parse-pattern` now collects comma-separated patterns into a
:ptuple after parse-pattern-cons, before the optional `as` alias.
The scrutinee side already built tuples via parse-tuple, so both
sides are now symmetric.
lru_cache.ml (iter 258) reverts its workaround back to the natural
form:
let rec take n lst = match n, lst with
| 0, _ -> []
| _, [] -> []
| _, h :: r -> h :: take (n - 1) r
607/607 regressions clean.
Functional LRU cache via association-list ordered most-recent-first.
Get / put both:
- find or remove the existing entry
- cons the fresh (k, v) to the front
- on put, trim the tail when over capacity
Sequence:
put 1 100; put 2 200; put 3 300
a = get 1 -> 100 (moves 1 to front)
put 4 400 (evicts 2)
b = get 2 -> -1 (no longer cached)
c = get 3 -> 300
d = get 1 -> 100
a + b + c + d = 499
Tests `match … with (k', v) :: rest when k' = k -> …` tuple-cons
patterns with `when` guards, `function` keyword for arg-less
match, recursive find/remove/take over the same list.
Parser limit found: `match n, lst with` ad-hoc tuple-scrutinee is
not yet supported (got "expected op -> got op ,"); workaround
uses outer `if` plus inner match.
171 baseline programs total.
Fenwick / Binary Indexed Tree for prefix sums. The classic
`i & -i` low-bit trick needs negative-aware AND, but our `land`
evaluator (iter 127, bitwise via floor/mod arithmetic) only handles
non-negative operands. Workaround: a portable lowbit helper that
finds the largest power of 2 dividing i:
let lowbit i =
let r = ref 1 in
while !r * 2 <= i && i mod (!r * 2) = 0 do
r := !r * 2
done;
!r
After building from [1;3;5;7;9;11;13;15]:
total = prefix_sum 8 = 64
update 1 by +100
after = prefix_sum 8 = 164
total + after = 228
Tests recursive update / prefix_sum chains via helper-extracted
lowbit; documents a non-obvious limit of the bitwise-emulation
layer.
168 baseline programs total.
Siamese construction for odd-order magic squares:
- place 1 at (0, n/2)
- for k = 2..n^2, move up-right with (x-1+n) mod n wrap
- if the target cell is taken, drop down one row instead
for n=5, magic constant = n*(n^2+1)/2 = 5*26/2 = 65
Returns the main-diagonal sum (65 by construction).
Tests 2D array via Array.init + Array.make, mod arithmetic with
the (x-1+n) mod n idiom for negative-safe wrap, nested begin/end
branches inside for-loop body.
166 baseline programs total.
Fibonacci via repeated-squaring matrix exponentiation:
[[1, 1], [1, 0]] ^ n = [[F(n+1), F(n)], [F(n), F(n-1)]]
Recursive O(log n) power:
let rec mpow m n =
if n = 0 then identity
else if n mod 2 = 0 then let h = mpow m (n / 2) in mul h h
else mul m (mpow m (n - 1))
Returns the .b cell after raising to the 30th power -> 832040 = F(30).
Tests record literal construction inside recursive function returns,
record field access (x.a etc), and pure integer arithmetic in the
matrix multiply.
165 baseline programs total.
Classic egg-drop puzzle DP:
dp[e][f] = 1 + min over k in [1, f] of
max(dp[e-1][k-1], dp[e][f-k])
For 2 eggs over 36 floors, the optimal worst-case is 8 trials
(closed form: triangular number bound).
Tests 2D DP with triple-nested for-loops, max-of-two via inline
if, large sentinel constant (100000000), mixed shifted indexing
(e-1) and (f-k) where both shift independently.
163 baseline programs total.
DFS topological sort — recurse on out-edges first, prepend after:
let rec dfs v =
if not visited.(v) then begin
visited.(v) <- true;
List.iter dfs adj.(v);
order := v :: !order
end
Same 6-node DAG as iter 230's Kahn's-algorithm baseline:
0 -> {1, 2}
1 -> {3}
2 -> {3, 4}
3 -> {5}
4 -> {5}
5
DFS order: [0; 2; 4; 1; 3; 5]
Horner fold: 0->0->2->24->241->2413->24135.
Complementary to topo_sort.ml (Kahn's BFS); tests recursive DFS
with no explicit stack + List.fold_left as a horner reduction.
160 baseline programs total.
LSD radix sort over base 10 digits. Per pass:
- 10 bucket-refs created via Array.init 10 (fun _ -> ref []) (each
closure call yields a distinct list cell)
- scan array, append each value to its digit's bucket
- flatten buckets back to the array in order
Input [170;45;75;90;802;24;2;66]
Output [2;24;45;66;75;90;170;802]
Sentinel: a.(0) + a.(7)*1000 = 2 + 802*1000 = 802002.
Tests array-of-refs with !buckets.(d) deref, list-mode bucket
sort within in-place array sort, unused for-loop var (`for _ =
1 to maxd`).
159 baseline programs total.
Minimum-coin DP with -1 sentinel for unreachable values:
let coin_min coins amount =
let dp = Array.make (amount + 1) (-1) in
dp.(0) <- 0;
for i = 1 to amount do
List.iter (fun c ->
if c <= i && dp.(i - c) >= 0 then begin
let cand = dp.(i - c) + 1 in
if dp.(i) < 0 || cand < dp.(i) then dp.(i) <- cand
end
) coins
done;
dp.(amount)
coin_min [1; 5; 10; 25] 67 = 6 (* 25+25+10+5+1+1 *)
Tests `if c <= i && dp.(i-c) >= 0 then` short-circuit guard;
relies on iter-242 fix so dp.(i-c) is not evaluated when c > i.
158 baseline programs total.
Recursive 4-way flood fill from every unvisited 1-cell:
let rec flood visited r c =
if r < 0 || r >= h || c < 0 || c >= w then 0
else if visited.(r).(c) || grid.(r).(c) = 0 then 0
else begin
visited.(r).(c) <- true;
1 + flood visited (r - 1) c
+ flood visited (r + 1) c
+ flood visited r (c - 1)
+ flood visited r (c + 1)
end
Grid (1s shown as #, 0s as .):
# # . # #
# . . . #
. . # . .
# # # # .
. . . # #
Largest component: {(2,2),(3,0),(3,1),(3,2),(3,3),(4,3),(4,4)} = 7.
Bounds check r >= 0 must short-circuit before visited/grid reads;
relies on the && / || fix from iter 242.
157 baseline programs total.
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.
Before: `:op` handler always evaluated both operands before dispatching
to ocaml-eval-op. For pure binops that's fine, but `&&` / `||` MUST
short-circuit:
if nr >= 0 && grid.(nr).(nc) = 0 then ...
When nr = -1, real OCaml never evaluates `grid.(-1)`. Our evaluator
did, and crashed with "nth: list/string and number".
Fix: special-case `&&` and `||` in :op dispatch, mirroring the same
pattern already used for `:=` and `<-`. Evaluate lhs, branch on it,
and only evaluate rhs when needed.
Latent since baseline 1 — earlier programs never triggered it because
the rhs was unconditionally safe.
bfs_grid.ml: shortest path through a 5x5 grid with walls. Standard
BFS using Queue.{push,pop,is_empty} + Array.init for the 2D distance
matrix. Path 0,0 -> ... -> 4,4 has length 8. 155 baseline programs
total.