-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathkey_gen_face_five.rs
177 lines (157 loc) · 5.77 KB
/
key_gen_face_five.rs
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use std::cmp;
use std::time::Instant;
pub fn main() {
println!("start key-gen-face-five");
// init
let mut t: u32; // t=trial key, k=index searched key
let mut c: usize; // sums counter
let mut valid: bool; // true if key is valid
let mut sums = [0; 50000]; // array of all possible sums of key[c[1-5]]
let mut key = [0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // init keys - empirical
// let sums_max_idx = sums.len();
println!("bootstrap -> keys={:?}", key);
let start = Instant::now();
for k in 3..11 {
println!("searching for k={}", k);
t = key[k - 1] + 1u32;
let interm = Instant::now();
valid = false;
while !valid {
key[k] = t;
let c_max = k + 1;
c = 0;
for c1 in 0..c_max {
for c2 in c1..c_max {
for c3 in c2..c_max {
for c4 in c3..c_max {
for c5 in c4..c_max {
if c1 != c5 {
// let bounded_c = cmp::min(c, sums_max_idx);
// let bounded_c = cmp::min(c, sums.len() - 1);
let bounded_c = cmp::min(c, sums.len() - 1);
sums[bounded_c] =
key[c1] + key[c2] + key[c3] + key[c4] + key[c5];
c += 1;
}
}
}
}
}
}
// for c1 in 0..c_max {
// for c2 in c1..c_max {
// for c3 in c2..c_max {
// for c4 in c3..c_max {
// for c5 in c4..c_max {
// if c1 != c5 {
// unsafe {
// sums[cmp::min(c, sums.len())] = key.get_unchecked(c1)
// + key.get_unchecked(c2)
// + key.get_unchecked(c3)
// + key.get_unchecked(c4)
// + key.get_unchecked(c5);
// c += 1;
// }
// }
// }
// }
// }
// }
// }
// v1 - debug mode
// let mut i: usize;
// let mut j: usize;
// valid = true;
// i = 0;
// loop {
// j = i + 1;
// loop {
// if sums[i] == sums[j] {
// valid = false;
// }
// j += 1;
// if !(valid && j < c) {
// break;
// }
// }
// i += 1;
// if !(valid && i < c - 1) {
// break;
// }
// }
// v2 - release mode with unsafe - fastest
let mut i: usize;
let mut j: usize;
i = 0;
valid = true;
loop {
j = i + 1;
loop {
if unsafe { sums.get_unchecked(i) == sums.get_unchecked(j) } {
valid = false;
}
j += 1;
if !(valid && j < c) {
break;
}
}
i += 1;
if !(valid && i < c - 1) {
break;
}
}
// v3 - release mode without unsafe - fastest safe
// let mut i;
// i = 0;
// valid = true;
// loop {
// if sums[i + 1..c].contains(&sums[i]) {
// valid = false;
// }
// i += 1;
// if !(valid && i < c - 1) {
// break;
// }
// }
// v3b - release mode without unsafe - fatest safe equivalent more compact
// valid = (0..c - 1).all(|i| !sums[i + 1..c].contains(&sums[i]));
// v4 - release mode without unsafe - less efficient ways
// let mut i: usize;
// i = 0;
// valid = true;
// loop {
// let sums_i = sums[i];
// for &sums_j in &sums[i + 1..c] {
// if sums_i == sums_j {
// valid = false;
// break;
// }
// }
// i += 1;
// if !(valid && i < c - 1) {
// break;
// }
// }
// v5 - release mode without unsafe - less efficient ways
// valid = true;
// for (i, s) in sums[..c - 1].iter().enumerate() {
// if sums[i + 1..c].contains(s) {
// valid = false;
// break;
// }
// }
if valid {
println!("key[{}]={:?}", k, t);
// println!("c={:?}", c); // ?!?? comment to allow bounded_c = len()-1 without perf impact
let end = Instant::now();
println!("\truntime for key[{}] = {:?}", k, (end - interm));
println!("\truntime for key[{}] = {:?}", k, (end - start));
} else {
t += 1;
}
}
}
let end = Instant::now();
println!("runtime = {:?}", (end - start));
println!("key={:?}", key);
}