From 7f8bf5f45545ff44cc8489b2ac3288b52d64d9d2 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 14:52:13 +0000 Subject: [PATCH] ocaml: phase 5.1 mortgage.ml baseline (monthly payment, 200k @ 5% / 30y = $1073) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standard amortising-mortgage formula: payment = P * r * (1 + r)^n / ((1 + r)^n - 1) where r = annual_rate / 12, n = years * 12. let payment principal annual_rate years = let r = annual_rate /. 12.0 in let n = years * 12 in let pow_r = ref 1.0 in for _ = 1 to n do pow_r := !pow_r *. (1.0 +. r) done; principal *. r *. !pow_r /. (!pow_r -. 1.0) For 200,000 at 5% over 30 years: monthly payment ~= $1073.64, int_of_float -> 1073. Manual (1+r)^n via for-loop instead of Float.pow keeps the program portable to any environment where pow is restricted. Tests float arithmetic precedence, for-loop accumulation in a float ref, int_of_float on the result. 70 baseline programs total — milestone. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/mortgage.ml | 10 ++++++++++ plans/ocaml-on-sx.md | 7 +++++++ 3 files changed, 18 insertions(+) create mode 100644 lib/ocaml/baseline/mortgage.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 019643c9..4b719c8a 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -40,6 +40,7 @@ "lambda_calc.ml": 7, "levenshtein.ml": 11, "memo_fib.ml": 75025, + "mortgage.ml": 1073, "merge_sort.ml": 44, "module_use.ml": 3, "newton_sqrt.ml": 1414, diff --git a/lib/ocaml/baseline/mortgage.ml b/lib/ocaml/baseline/mortgage.ml new file mode 100644 index 00000000..5119c516 --- /dev/null +++ b/lib/ocaml/baseline/mortgage.ml @@ -0,0 +1,10 @@ +let payment principal annual_rate years = + let r = annual_rate /. 12.0 in + let n = years * 12 in + let pow_r = ref 1.0 in + for _ = 1 to n do pow_r := !pow_r *. (1.0 +. r) done; + principal *. r *. !pow_r /. (!pow_r -. 1.0) + +;; + +int_of_float (payment 200000.0 0.05 30) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index c36c914a..f47ef114 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,13 @@ _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 — mortgage.ml baseline (monthly mortgage + payment formula, 200k @ 5% / 30y → $1073). Manual `(1+r)^n` + computed via for-loop because `Float.pow` may not be available + for arbitrary args here. Then plugs into `principal * r * + (1+r)^n / ((1+r)^n - 1)`. Tests float arithmetic precedence, + for-loop accumulation in a float ref, int_of_float on the result. + 70 baseline programs total — milestone. - 2026-05-09 Phase 5.1 — group_consec.ml baseline (group consecutive equals into sublists, 5*10 + 3 = 53). Inner `collect cur acc tail` walks while head matches `cur`, accumulates into `acc`,