diff --git a/lib/ocaml/baseline/euler40_small.ml b/lib/ocaml/baseline/euler40_small.ml new file mode 100644 index 00000000..7905f46e --- /dev/null +++ b/lib/ocaml/baseline/euler40_small.ml @@ -0,0 +1,22 @@ +let euler40 () = + let buf = Buffer.create 4096 in + let len = ref 0 in + let i = ref 1 in + while !len < 1500 do + let s = string_of_int !i in + Buffer.add_string buf s; + len := !len + String.length s; + i := !i + 1 + done; + let s = Buffer.contents buf in + let prod = ref 1 in + let positions = [1; 10; 100; 1000] in + List.iter (fun p -> + let c = s.[p - 1] in + prod := !prod * (Char.code c - Char.code '0') + ) positions; + !prod + +;; + +euler40 () diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index d0b59c2f..2b64e4bb 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -36,6 +36,7 @@ "euler29_small.ml": 15, "euler30_cube.ml": 1301, "euler34_small.ml": 145, + "euler40_small.ml": 15, "euler3.ml": 29, "euler4_small.ml": 9009, "euler5.ml": 232792560, diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 01a85248..248b321f 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,12 @@ _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-10 Phase 5.1 — euler40_small.ml baseline (Champernowne + digit-product at 1, 10, 100, 1000 = 1*1*5*3 = 15). Builds the + Champernowne string until ≥1500 chars; tracks length separately + from the Buffer to avoid O(n²) `String.length (Buffer.contents + buf)` reallocation. Real PE40 uses positions up to 10^6 (answer + 210). 122 baseline programs total. - 2026-05-09 Phase 5.1 — euler34_small.ml baseline (numbers equal to sum of factorials of digits, ≤2000 = 145). 145 = 1!+4!+5! = 1+24+120. The other "factorion" 40585 is the only number above