use num::PrimInt;
use serde::{Deserialize, Serialize};
use crate::combrs::binom;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
pub struct SetSpace {
pub num_uni: usize,
}
impl SetSpace {
pub fn new(num_uni: usize) -> Self {
Self { num_uni }
}
pub fn enc<I: PrimInt, O: PrimInt>(&self, seq: &[I]) -> O {
assert!(seq.len() == self.num_uni, "expected sequence to be complete");
let mut idx = 0usize;
for (i, a) in seq.iter().map(|x| x.to_usize().unwrap()).enumerate() {
idx = idx + (1usize << a);
}
O::from::<usize>(idx).unwrap()
}
pub fn dec<I: PrimInt, O: PrimInt>(&self, idx: I, items: &mut [O]) {
assert!(items.len() == self.num_uni, "expected sequence to be complete");
let mut idx = idx.to_usize().unwrap();
for i in (1..=self.num_uni).rev() {
if (1usize << i) & idx == 0 {
items[i] = O::from::<usize>(i).unwrap();
}
idx -= 1usize << i;
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
pub struct BagSpace {
pub num_uni: usize,
pub num_seq: usize,
}
impl BagSpace {
pub fn new(num_uni: usize, num_seq: usize) -> Self {
Self { num_uni, num_seq }
}
pub fn enc<I: PrimInt, O: PrimInt>(&self, seq: &[I]) -> O {
assert!(seq.len() == self.num_seq, "expected sequence to be complete");
let mut idx = 0usize;
for (i, a) in seq.iter().map(|x| x.to_usize().unwrap()).enumerate() {
idx = idx + binom(a + i, i + 1);
}
O::from::<usize>(idx).unwrap()
}
pub fn dec<I: PrimInt, O: PrimInt>(&self, idx: I, items: &mut [O]) {
assert!(items.len() == self.num_seq, "expected sequence to be complete");
let mut idx = idx.to_usize().unwrap();
let mut a = self.num_uni + self.num_seq - 1usize;
let mut pos = self.num_seq - 1;
for i in (1..=self.num_seq).rev() {
while binom(a, i) > idx {
a -= 1;
}
items[pos] = O::from::<usize>(a - pos).unwrap();
if i == 1 {
break;
}
idx -= binom(a, i);
a -= 1;
pos -= 1;
}
}
}