-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfannkuch.impala
92 lines (81 loc) · 1.65 KB
/
fannkuch.impala
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
80
81
82
83
84
85
86
87
88
89
90
91
92
extern "C" {
fn print_int(int) -> ();
}
static mut s = [0, .. 16];
static mut t = [0, .. 16];
static mut max_n = 12;
static mut maxflips = 0;
static mut odd = 0;
static mut checksum = 0;
fn take_address(a: &[int * 16]) -> () {}
fn range(a: int, b: int, body: fn(int, fn())) -> () {
if a < b {
body(a);
range(a+1, b, body, return)
}
}
fn flip() -> int {
for i in range(0, max_n) {
t(i) = s(i)
}
let mut i = 1;
while true {
let mut x = 0;
let mut y = t(0);
while x < y {
let c = t(x);
t(x++) = t(y);
t(y--) = c;
}
++i;
if t(t(0)) == 0 {
break()
}
}
i
}
fn rotate(n: int) -> () {
let c = s(0);
for i in range(1, n+1) {
s(i-1) = s(i);
}
s(n) = c;
}
/* Tompkin-Paige iterative perm generation */
fn tk(n: int) -> () {
let mut c = [0, .. 16];
take_address(&c); // HACK to prevent SSA contruction of c
let mut i = 0;
while i < n {
rotate(i);
if c(i) >= i {
c(i++) = 0;
continue()
}
++c(i);
i = 1;
odd = !odd;
if s(0) != 0 {
let f =
if s(s(0)) != 0 {
flip()
} else {
1
};
if f > maxflips {
maxflips = f;
}
checksum += if odd != 0 { -f } else { f }
}
}
}
fn main(n: int) -> () {
max_n = n;
for i in range(0, max_n) {
s(i) = i;
}
tk(max_n);
print_int(checksum);
print_int(max_n);
print_int(maxflips);
}