From 07de86365e95de374f8b0cfeded08ff968ccf48e Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 15:42:01 +0000 Subject: [PATCH] ocaml: 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 a doubled value > 9, subtract 9. Sum must be divisible by 10: 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 Test cases: '79927398713' valid '79927398710' invalid '4532015112830366' valid (real Visa test) '1234567890123456' invalid sum = 2 Tests right-to-left index walk via 'n - 1 - i', Char.code '0' arithmetic for digit conversion, and nested if-then-else. 75 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/luhn.ml | 20 ++++++++++++++++++++ plans/ocaml-on-sx.md | 10 ++++++++++ 3 files changed, 31 insertions(+) create mode 100644 lib/ocaml/baseline/luhn.ml 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