forked from cgay/shootout
-
Notifications
You must be signed in to change notification settings - Fork 2
/
fannkuch.dylan
79 lines (70 loc) · 2.08 KB
/
fannkuch.dylan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module: fannkuch
define constant <int-vector> = limited(<vector>, of: <integer>);
define function fannkuch (n :: <integer>)
=> (result :: <integer>, checksum :: <integer>);
let perm :: <int-vector> = make(<int-vector>,size: n,fill: 0);
let perm1 = make(<int-vector>,size: n,fill: 0);
let count = make(<int-vector>,size: n,fill: 0);
let max-flip-count :: <integer> = 0;
let m :: <integer> = n - 1;
let r :: <integer> = n;
let odd :: <boolean> = #t;
let checksum :: <integer> = 0;
for (i from 0 below n)
perm1[i] := i;
end for;
block(return)
while (#t)
while (r ~= 1)
count[r - 1] := r;
r := r - 1;
end while;
odd := ~odd;
if (~ (perm1[0] = 0))
for (i from 0 below n)
perm[i] := perm1[i];
end for;
let flip-count :: <integer> = 0;
while (perm[0] ~= 0)
let k :: <integer> = perm[0];
let k2 :: <integer> = floor/(k + 1, 2);
for(i from 0 below k2)
let tmp = perm[i];
perm[i] := perm[k - i];
perm[k - i] := tmp;
end for;
flip-count := flip-count + 1;
end while;
if (flip-count > max-flip-count)
max-flip-count := flip-count;
end if;
checksum := checksum + if (odd) -flip-count else flip-count end;
end if;
block(break)
while(#t)
if (r = n)
return(max-flip-count, checksum);
end if;
let perm0 :: <integer> = perm1[0];
let i :: <integer> = 0;
while (i < r)
let j = i + 1;
perm1[i] := perm1[j];
i := j;
end while;
perm1[r] := perm0;
count[r] := count[r] - 1;
if (count[r] > 0)
break();
end if;
r := r + 1;
end while;
end block;
end while;
end block;
end function fannkuch;
begin
let arg = string-to-integer(element(application-arguments(), 0, default: "10"));
let (max-flips, checksum) = fannkuch(arg);
format-out("%=\nPfannkuchen(%=) = %d\n", checksum, arg, max-flips);
end;