pub fn skilling_transform(brgc: Vec<u32>, n: u32, p: u32) -> Vec<u32> {
brgc.iter()
.map(|hilbert_index| hilbert_index_to_hilbert_coordinates(hilbert_index, n, p))
.collect()
}
fn hilbert_index_to_hilbert_coordinates(hilbert_index: &u32, n: u32, p: u32) -> u32 {
let mut hilbert_index_bitvec = into_bit_vec(*hilbert_index, (n * p) as usize);
for r in (0..(&hilbert_index_bitvec.len() - n as usize)).rev() {
if !hilbert_index_bitvec[r as usize] {
let offset = r % n as usize;
let mut s = (p * n - n) as usize + offset;
let mut q = (p * n - n) as usize;
while q > r {
hilbert_index_bitvec.swap(q, s);
q -= n as usize;
s -= n as usize;
}
} else {
let mut i = n as usize * p as usize - n as usize;
while i > r && i >= n as usize {
hilbert_index_bitvec[i] = !hilbert_index_bitvec[i];
i -= n as usize;
}
}
}
into_u32(hilbert_index_bitvec)
}
fn into_bit_vec(int: u32, length: usize) -> Vec<bool> {
let mut bitvec = Vec::<bool>::new();
format!("{int:b}")
.chars()
.for_each(|bit| bitvec.push(bit == '1'));
let leading_false_count = length - bitvec.len();
let mut leading = Vec::<bool>::new();
for _ in 0..leading_false_count {
leading.push(false);
}
leading.extend(bitvec);
leading
}
fn into_u32(bitvec: Vec<bool>) -> u32 {
let bitstring: String = bitvec
.iter()
.map(|bit| if *bit { '1' } else { '0' })
.collect();
u32::from_str_radix(&bitstring, 2).unwrap()
}