diff --git a/lib/ocaml/baseline/coin_change.ml b/lib/ocaml/baseline/coin_change.ml new file mode 100644 index 00000000..5743a879 --- /dev/null +++ b/lib/ocaml/baseline/coin_change.ml @@ -0,0 +1,15 @@ +let coin_change coins target = + let dp = Array.make (target + 1) (target + 1) in + dp.(0) <- 0; + for i = 1 to target do + List.iter (fun c -> + if c <= i && dp.(i - c) + 1 < dp.(i) then + dp.(i) <- dp.(i - c) + 1 + ) coins + done; + if dp.(target) > target then -1 + else dp.(target) + +;; + +coin_change [1; 5; 10; 25] 67 diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 5e4f9195..6e0e9145 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -10,6 +10,7 @@ "caesar.ml": 215, "calc.ml": 13, "closures.ml": 315, + "coin_change.ml": 6, "csv.ml": 10, "exception_handle.ml": 4, "expr_eval.ml": 16, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index aabe7b2e..0d6bb898 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,14 @@ _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-09 Phase 5.1 โ€” coin_change.ml baseline (min coin DP, 67ยข + with [1;5;10;25] โ†’ 6 coins). Bottom-up DP: `dp[i]` = min coins + for amount i. For each amount 1..target, iterate coins and + relax `dp[i] = min(dp[i], dp[i-c] + 1)`. Sentinel `target + 1` + represents "impossible" since any real solution uses at most + target coins. 67 = 25+25+10+5+1+1 = 6 coins. Exercises + Array.make + arr.(i) + arr.(i) <- v + nested for/List.iter + + guard `c <= i`. 47 baseline programs total. - 2026-05-09 Phase 5.1 โ€” kadane.ml baseline (Kadane's max subarray sum = 6). Classic O(n) algorithm using two refs and `max`. For [-2;1;-3;4;-1;2;1;-5;4] the optimal subarray is [4;-1;2;1] = 6.