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
#[rustfmt::skip]
fn odd(n: usize) -> Vec<Vec<usize>> {
(0..n).map(|r|
(0..n).map(|c|
n * (((c + 1) + (r + 1) - 1 + (n >> 1)) % n) + (((c + 1) + (2 * (r + 1)) - 2) % n) + 1
).collect()
).collect()
}
#[rustfmt::skip]
fn even(n: usize) -> Vec<Vec<usize>> {
let size = n * n;
let half = n / 2;
let sub_square_size = size / 4;
let sub_square = odd(half);
let quadrant_factors = [0, 2, 3, 1];
let cols_left = half / 2;
let cols_right = cols_left - 1;
(0..n)
.map(|r| {
(0..n)
.map(|c| {
let cond = (c < cols_left || c >= n - cols_right || c == cols_left && r % half == cols_left) && !(c == 0 && r % half == cols_left);
let local = if cond { if r >= half { r - half } else { r + half } } else { r };
let quadrant = local / half * 2 + c / half;
let v = sub_square[local % half][c % half];
v + quadrant_factors[quadrant] * sub_square_size
})
.collect()
})
.collect()
}
#[rustfmt::skip]
fn double_even(n: usize) -> Vec<Vec<usize>> {
let bits = 0b1001_0110_0110_1001usize;
let size = n * n;
let sub = n / 4;
let mut i = 0;
(0..n)
.map(|r| {
(0..n)
.map(|c| {
i += 1;
let bit_pos = c / sub + (r / sub) * 4;
if bits & (1 << bit_pos) != 0 { i } else { size - i + 1 }
})
.collect()
})
.collect()
}
pub fn magic(n: usize) -> Vec<Vec<usize>> {
if n == 0 | 2 {
vec![]
}
else if n % 2 != 0 {
odd(n)
}
else if n % 4 != 0 {
even(n)
}
else {
double_even(n)
}
}
pub fn magic_print(n: usize) {
let width = (n * n).to_string().len() + 1;
let sum = (n * n + 1) * n / 2;
println!("The sum of the rank-{} square is {}.", n, sum);
for row in magic(n) {
for em in row {
print!("{e:>w$}", e = em, w = width);
}
println!();
}
}