man_or_boy/man_or_boy.fz
// using man_or_boy as a simple performance benchmark
//
// This calculates Knuth's man-or-boy function for the values 0..14
// repeatedly 200 times.
//
// Note that this is heavily recursive, it requires a large stack.
man_or_boy is
a(k mutate.new i32, x1, x2, x3, x4, x5 () -> i32) i32 is
b => k <- k.get - 1; a k (() -> b) x1 x2 x3 x4
if k.get <= 0 x4() + x5() else b
k(n i32) ()->i32 is
()->n
test(n, max, expected i32) i32
post
test.this.result = expected // NYI: misusing postcondition, check does not work yet
is
res := mut 0
for i in 1..n do
(0..max) | (n) ->
res <- res.get + (a (mut n) k( 1) k(-1) k(-1) k( 1) k( 0))
say "$n * sum (n in 0..$max: man_or_boy(n)) = $res"
res.get
// test(200, 12, -107200) -- about 16s
// test(200, 13, -235600) -- about 40s
_ := test(200, 14, -524800) // -- about 10min
// test(200, 16, -2623600) -- about 5h, swapping memory
last changed: 2023-11-14