diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 953cb99a..b7f41169 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -35,6 +35,7 @@ "fizzbuzz.ml": 57, "flatten_tree.ml": 28, "list_ops.ml": 30, + "luhn.ml": 2, "mat_mul.ml": 621, "max_path_tree.ml": 11, "mod_inverse.ml": 27, diff --git a/lib/ocaml/baseline/luhn.ml b/lib/ocaml/baseline/luhn.ml new file mode 100644 index 00000000..21f3ce72 --- /dev/null +++ b/lib/ocaml/baseline/luhn.ml @@ -0,0 +1,20 @@ +let luhn s = + let n = String.length s in + let total = ref 0 in + for i = 0 to n - 1 do + let d = Char.code s.[n - 1 - i] - Char.code '0' in + let v = if i mod 2 = 1 then + let dd = d * 2 in + if dd > 9 then dd - 9 else dd + else d + in + total := !total + v + done; + !total mod 10 = 0 + +;; + +(if luhn "79927398713" then 1 else 0) ++ (if luhn "79927398710" then 1 else 0) ++ (if luhn "4532015112830366" then 1 else 0) ++ (if luhn "1234567890123456" then 1 else 0) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 0e36da8e..f29b437d 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-09 Phase 5.1 — luhn.ml baseline (Luhn check digit, 2/4 + inputs valid). Walks digits right-to-left, doubles every other + starting from the second-from-right; if doubled value > 9 + subtract 9. Sum must be divisible by 10. Tests: + 79927398713 ✓ valid + 79927398710 ✗ + 4532015112830366 ✓ valid (real Visa test number) + 1234567890123456 ✗ + Sum = 2. Tests right-to-left index walk + Char.code '0' arithmetic + + nested if-then-else. 75 baseline programs total. - 2026-05-09 Phase 5.1 — triangle.ml baseline (Pascal-shape min path sum, 2+3+5+1 = 11). Bottom-up DP over the triangle: 2