Man or boy test: Difference between revisions

→‎F#: Add CPS version of straightforward approach.
m (syntax highlighting fixup automation)
imported>GLChapman
(→‎F#: Add CPS version of straightforward approach.)
 
(6 intermediate revisions by 5 users not shown)
Line 518:
</pre>
 
=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> HIMEM = PAGE + 200000000 : REM Increase recursion depth
Line 1,380 ⟶ 1,381:
 
=={{header|Elena}}==
ELENA 46.1x:
<syntaxhighlight lang="elena">import extensions;
 
Line 1,401 ⟶ 1,402:
public program()
{
for(int n := 0,; n <= 14,; n += 1)
{
console.printLine(A(n,{^1},{^-1},{^-1},{^1},{^0}))
Line 1,460 ⟶ 1,461:
▶ man_or_boy.(14) #⇒ -1446
▶ man_or_boy.(20) #⇒ [error] Too many processes
</pre>
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
fun A = int by int k, fun x1, fun x2, fun x3, fun x4, fun x5
fun B = int by block do return A(--k, B, x1, x2, x3, x4) end
return when(k <= 0, x4() + x5(), B())
end
fun C = fun by int i
return int by block do return i end
end
for int i = 0; i <= 11; i++
writeLine("A(" + i + ") = " + A(i, C(1), C(-1), C(-1), C(1), C(0) ))
end
</syntaxhighlight>
{{out}}
<pre>
A(0) = 1
A(1) = 0
A(2) = -2
A(3) = 0
A(4) = 1
A(5) = 0
A(6) = 1
A(7) = -1
A(8) = -10
A(9) = -30
A(10) = -67
A(11) = -138
</pre>
 
Line 1,575 ⟶ 1,605:
0
</syntaxhighlight>
 
F# supports tail calls (when compiled in Release mode), so you can also avoid stack overflow using the straightforward approach modified to use continuation-passing style:
<syntaxhighlight lang="fsharp">
[<EntryPoint>]
let main (args : string[]) =
let k = int(args.[0])
 
let l x cont = cont x
 
let rec a k x1 x2 x3 x4 x5 cont =
if k <= 0 then
x4 (fun n4 -> x5 (fun n5 -> cont (n4+n5)))
else
let mutable k = k
let rec b cont =
k <- k - 1
a k b x1 x2 x3 x4 cont
b cont
 
a k (l 1) (l -1) (l -1) (l 1) (l 0) (printfn "%d")
 
0
</syntaxhighlight>
 
 
=={{header|Fantom}}==
Line 3,733 ⟶ 3,787:
===CLI===
In Wren, a fiber's stack starts quite small but is then increased as needed, apparently limited only by available memory. Anyway, satisfying the test for k up to 20 is unlikely to be a problem on a modern machine.
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var a
Line 3,779 ⟶ 3,833:
{{libheader|Wren-fmt}}
Based on Go's 'faster' version this runs in about 15.2 seconds which (surprisingly) is slightly faster than Go itself (16.6 seconds).
<syntaxhighlight lang="ecmascriptwren">/* man_or_boy_test_gmpMan_or_boy_test_2.wren */
 
import "./gmp" for Mpz
Line 3,828 ⟶ 3,882:
<pre>
Same as Go 'faster' version.
</pre>
 
=={{header|Zig}}==
'''Works with:''' 0.10.x, 0.11.x, 0.12.0-dev.1390+94cee4fb2
 
<syntaxhighlight lang="zig">const Record = struct {
yieldFn: *const fn (record: *Record) i32,
 
k: *i32 = undefined,
x1: *Record = undefined,
x2: *Record = undefined,
x3: *Record = undefined,
x4: *Record = undefined,
x5: *Record = undefined,
 
inline fn run(record: *Record) i32 {
return record.yieldFn(record);
}
 
pub fn A(record: *Record) i32 {
return if (record.k.* <= 0)
record.x4.run() + record.x5.run()
else
record.B();
}
 
fn B(record: *Record) i32 {
record.k.* -= 1;
 
var k_copy_on_stack: i32 = record.k.*;
 
var b: Record = .{
.yieldFn = &Record.B,
 
.k = &k_copy_on_stack,
.x1 = record,
.x2 = record.x1,
.x3 = record.x2,
.x4 = record.x3,
.x5 = record.x4,
};
return b.A();
}
};
 
const numbers = struct {
fn positiveOne(unused_record: *Record) i32 {
_ = unused_record;
return 1;
}
 
fn zero(unused_record: *Record) i32 {
_ = unused_record;
return 0;
}
 
fn negativeOne(unused_record: *Record) i32 {
_ = unused_record;
return -1;
}
};
 
const std = @import("std");
 
pub fn main() void {
var i: u31 = 0;
while (i <= 31) : (i += 1) {
var k: i32 = i;
var @"+1_record": Record = .{ .yieldFn = &numbers.positiveOne };
var @"0_record": Record = .{ .yieldFn = &numbers.zero };
var @"-1_record": Record = .{ .yieldFn = &numbers.negativeOne };
 
var record: Record = .{
.yieldFn = &Record.B,
 
.k = &k,
.x1 = &@"+1_record",
.x2 = &@"-1_record",
.x3 = &@"-1_record",
.x4 = &@"+1_record",
.x5 = &@"0_record",
};
 
std.debug.print("[{d:>3}] = {d}\n", .{ i, record.A() });
}
}</syntaxhighlight>
 
{{out}}
<pre>
$ zig build-exe -OReleaseSmall -fstrip src/man_or_boy_test.zig
$ ulimit -s
8192
 
$ ./man_or_boy_test
[ 0] = 1
[ 1] = 0
[ 2] = -2
[ 3] = 0
[ 4] = 1
[ 5] = 0
[ 6] = 1
[ 7] = -1
[ 8] = -10
[ 9] = -30
[ 10] = -67
[ 11] = -138
[ 12] = -291
[ 13] = -642
[ 14] = -1446
[ 15] = -3250
[ 16] = -7244
[ 17] = -16065
[ 18] = -35601
[1] 22315 segmentation fault ./man_or_boy_test
 
$ ulimit -s 71296
$ ./man_or_boy_test
[ 0] = 1
[ 1] = 0
[ 2] = -2
[ 3] = 0
[ 4] = 1
[ 5] = 0
[ 6] = 1
[ 7] = -1
[ 8] = -10
[ 9] = -30
[ 10] = -67
[ 11] = -138
[ 12] = -291
[ 13] = -642
[ 14] = -1446
[ 15] = -3250
[ 16] = -7244
[ 17] = -16065
[ 18] = -35601
[ 19] = -78985
[ 20] = -175416
[1] 22384 segmentation fault ./man_or_boy_test
</pre>
 
Anonymous user