From ac19b7aced499c5deded800b62edba8f0484dc70 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 11:19:23 +0000 Subject: [PATCH] ocaml: phase 5.1 bigint_add.ml baseline (digit-list bignum add, 1+18+9 = 28) Recursive 4-arm match on (a, b) tuples threading a carry: match (a, b) with | ([], []) -> if carry = 0 then [] else [carry] | (x :: xs, []) -> (s mod 10) :: aux xs [] (s / 10) where s = x + carry | ([], y :: ys) -> ... | (x :: xs, y :: ys) -> ... where s = x + y + carry Little-endian digit lists. Three tests: [9;9;9] + [1] = [0;0;0;1] (=1000, digit sum 1) [5;6;7] + [8;9;1] = [3;6;9] (=963, digit sum 18) [9;9;9;9;9;9;9;9] + [1] length 9 (carry propagates 8x) Sum = 1 + 18 + 9 = 28. Exercises tuple-pattern match on nested list-cons with the integer arithmetic and carry-threading idiom typical of multi-precision implementations. 52 baseline programs total. --- lib/ocaml/baseline/bigint_add.ml | 24 ++++++++++++++++++++++++ lib/ocaml/baseline/expected.json | 1 + plans/ocaml-on-sx.md | 9 +++++++++ 3 files changed, 34 insertions(+) create mode 100644 lib/ocaml/baseline/bigint_add.ml diff --git a/lib/ocaml/baseline/bigint_add.ml b/lib/ocaml/baseline/bigint_add.ml new file mode 100644 index 00000000..87a5a195 --- /dev/null +++ b/lib/ocaml/baseline/bigint_add.ml @@ -0,0 +1,24 @@ +let bigint_add a b = + let rec aux a b carry = + match (a, b) with + | ([], []) -> if carry = 0 then [] else [carry] + | (x :: xs, []) -> + let s = x + carry in + (s mod 10) :: aux xs [] (s / 10) + | ([], y :: ys) -> + let s = y + carry in + (s mod 10) :: aux [] ys (s / 10) + | (x :: xs, y :: ys) -> + let s = x + y + carry in + (s mod 10) :: aux xs ys (s / 10) + in + aux a b 0 + +;; + +let r1 = bigint_add [9;9;9] [1] in +let r2 = bigint_add [5;6;7] [8;9;1] in +let r3 = bigint_add [9;9;9;9;9;9;9;9] [1] in +List.fold_left (+) 0 r1 + + List.fold_left (+) 0 r2 + + List.length r3 diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 26b0e10a..3f93f13d 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -2,6 +2,7 @@ "ackermann.ml": 125, "anagrams.ml": 3, "bag.ml": 3, + "bigint_add.ml": 28, "bits.ml": 21, "balance.ml": 3, "bfs.ml": 6, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 8c117cba..8fdf4adc 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,15 @@ _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 — bigint_add.ml baseline (digit-list big-num + add, 28 = 1+18+9). Recursive 4-arm match on `(a, b)` tuples + threading a carry: `(x::xs, y::ys) -> (s mod 10) :: aux xs ys (s + / 10)`. Three test cases: + bigint_add [9;9;9] [1] = [0;0;0;1] (digit sum 1) + bigint_add [5;6;7] [8;9;1] = [3;6;9] (digit sum 18, 765+198=963) + bigint_add [9;9;9;9;9;9;9;9] [1] length 9 (carry propagates 8 places) + Sum: 1 + 18 + 9 = 28. Exercises tuple-pattern match on nested + list-cons + integer arithmetic. 52 baseline programs total. - 2026-05-09 Phase 5.1 — expr_simp.ml baseline (symbolic expression simplifier, eval (simp e) = 22). Recursive ADT with three constructors (Num/Add/Mul). simp does bottom-up rewrite using