use std::collections::BTreeSet;
pub fn get_companion_layer(z: usize, x: usize, y: usize, z_y: usize, q: usize) -> usize {
if x == z_y {
return z;
}
let q_pow_y = q.pow(y as u32);
z - z_y * q_pow_y + x * q_pow_y
}
pub fn get_plane_vector(z: usize, t: usize, q: usize) -> Vec<usize> {
let mut result = vec![0usize; t];
let mut remaining = z;
for i in 0..t {
result[t - 1 - i] = remaining % q;
remaining /= q;
}
result
}
pub fn get_max_iscore(erased_chunks: &BTreeSet<usize>, t: usize, q: usize, sub_chunk_no: usize) -> usize {
let mut max_iscore = 0;
for z in 0..sub_chunk_no {
let plane_vec = get_plane_vector(z, t, q);
let mut iscore = 0;
for &erased in erased_chunks {
let y = erased / q;
let x = erased % q;
if y < t && plane_vec[y] == x {
iscore += 1;
}
}
max_iscore = max_iscore.max(iscore);
}
max_iscore
}
pub fn set_planes_sequential_decoding_order(
order: &mut [usize],
erasures: &BTreeSet<usize>,
t: usize,
q: usize,
sub_chunk_no: usize,
) {
let mut planes_with_is: Vec<(usize, usize)> = (0..sub_chunk_no)
.map(|z| {
let plane_vec = get_plane_vector(z, t, q);
let is = erasures.iter().filter(|&&e| {
let y = e / q;
let x = e % q;
y < t && plane_vec[y] == x
}).count();
(z, is)
})
.collect();
planes_with_is.sort_by_key(|&(z, is)| (is, z));
for (i, (z, _)) in planes_with_is.iter().enumerate() {
if i < order.len() {
order[i] = *z;
}
}
}
#[inline]
pub fn is_unpaired(x: usize, y: usize, z: usize, q: usize) -> bool {
let z_y = (z / q.pow(y as u32)) % q;
x == z_y
}
#[inline]
pub fn get_z_y(z: usize, y: usize, q: usize) -> usize {
(z / q.pow(y as u32)) % q
}
#[inline]
pub fn node_to_xy(node: usize, q: usize) -> (usize, usize) {
(node % q, node / q)
}
#[inline]
pub fn xy_to_node(x: usize, y: usize, q: usize) -> usize {
y * q + x
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_plane_vector() {
assert_eq!(get_plane_vector(0, 2, 2), vec![0, 0]);
assert_eq!(get_plane_vector(1, 2, 2), vec![0, 1]);
assert_eq!(get_plane_vector(2, 2, 2), vec![1, 0]);
assert_eq!(get_plane_vector(3, 2, 2), vec![1, 1]);
assert_eq!(get_plane_vector(5, 2, 3), vec![1, 2]);
}
#[test]
fn test_companion_layer() {
let q = 2;
let z_y = get_z_y(2, 0, q);
assert_eq!(z_y, 0);
assert_eq!(get_companion_layer(2, 1, 0, z_y, q), 3);
let z_y = get_z_y(3, 0, q);
assert_eq!(z_y, 1);
assert_eq!(get_companion_layer(3, 1, 0, z_y, q), 3); }
#[test]
fn test_is_unpaired() {
let q = 2;
assert!(is_unpaired(0, 0, 0, q));
assert!(is_unpaired(0, 1, 0, q));
assert!(!is_unpaired(1, 0, 0, q));
assert!(is_unpaired(1, 0, 3, q));
assert!(is_unpaired(1, 1, 3, q));
assert!(!is_unpaired(0, 0, 3, q));
}
#[test]
fn test_node_conversion() {
let q = 3;
assert_eq!(node_to_xy(0, q), (0, 0));
assert_eq!(node_to_xy(5, q), (2, 1));
assert_eq!(xy_to_node(2, 1, q), 5);
}
}