#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(unused_parens)]
#![allow(unused_assignments)]
#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(dead_code)]
pub struct compactstr<const N : usize>
{
chrs : [u8; N],
olen : usize, clen : usize, }
impl<const N:usize> compactstr<N>
{
pub fn new() -> Self {
compactstr {
chrs : [0;N],
olen : 0,
clen : 0,
}
}
fn repeats(&self) -> usize {
let mut ax = 0;
let mut counts = [0u8;N];
for i in 0..self.clen {
let uc = self.chrs[i] as usize;
if uc != 0 { ax += counts[uc] as usize; counts[uc] += 1; }
} ax
}
fn rle(s:&str) -> Self {
let bytes = s.as_bytes();
let blen = bytes.len();
let mut compact = compactstr::new();
if blen==0 {return compact;}
compact.chrs[0] = bytes[0];
compact.chrs[1] = 1; let mut ci = 1; for bi in 1..blen { if bytes[bi] == bytes[bi-1] {
compact.chrs[ci] += 1;
}
else if ci+2 >= N {break;}
else {
compact.chrs[ci+1] = bytes[bi];
compact.chrs[ci+2] = 1;
ci += 2;
}
} compact
}
fn inverse_rle<const M:usize>(&self) -> [u8;M] { let mut ax = [0u8;M];
let mut i = 0; let mut k = 0; while i+1<self.clen && k<M {
for _ in 0..self.chrs[i+1] {
if k<M {ax[k] = self.chrs[i];} else {break;}
k += 1;
} i += 2;
} ax
}
}
pub fn count_repeats(s:&str) -> usize {
let bytes = s.as_bytes();
let mut ax = 0;
let mut counts = [0u8;256];
for i in 0..s.len() {
let uc = bytes[i] as usize;
ax += counts[uc] as usize;
counts[uc] += 1;
} ax
}
pub fn compression_ratio(s:&str) -> f32 {
let reps = count_repeats(s) as f32;
if s.len()==0 {0.0} else { reps / (s.len() as f32) }
}
fn rename<const M:usize>(t:&mut [u8;M], sa:&mut [usize;M],n:usize,) -> [usize;M]
{
assert!(M>=256 && n<M);
let mut tp = [0usize;M]; let mut counts = [0usize;256];
for bi in 0..n { counts[t[bi] as usize] += 1;
} let mut sum = 0;
for k in 0..256 { if counts[k]>0 {
sa[k] = sum;
sum += counts[k];
if sum>=n {break;}
}
} for bi in 0..n {
tp[bi] = sa[t[bi] as usize];
}
let mut chartype = false; let mut i = n-1;
tp[n-1] = 0; while i>0 {
chartype = t[i-1]>t[i] || (t[i-1]==t[i] && chartype);
if !chartype { tp[i-1] = sa[t[i-1] as usize] + counts[t[i-1] as usize] - 1;
}
i -= 1;
}
use SAEntry::*;
let mut SA = [Counter(0);M];
SA[0] = Index(n-1);
let mut prevtype = false; chartype = false;
i = n-1;
let mut lmschars = 0; while i>0 {
prevtype = t[i-1]>t[i] || (t[i-1]==t[i] && chartype);
if !chartype && prevtype { match SA[tp[i]] {
Counter(n) => { SA[tp[i]] = Counter(n+1); },
_ => {},
} lmschars += 1;
} chartype = prevtype;
i -= 1;
} chartype = false; i = n-1;
while i>0 {
prevtype = t[i-1]>t[i] || (t[i-1]==t[i] && chartype);
if !chartype && prevtype { match SA[tp[i]] {
Counter(1) => {
SA[tp[i]] = Index(i);
}
Counter(count) if count>1 => {
SA[tp[i]-count+1] = Index(i);
SA[tp[i]] = Counter(count-1);
},
_ => {},
} } chartype = prevtype;
i -= 1;
}
println!("SA: {:?}",&SA[..n]);
i = n-1; chartype = false;
while i>0 {
chartype = t[i-1]>t[i] || (t[i-1]==t[i] && chartype);
if chartype { if let Counter(c) = SA[tp[i]] {
SA[tp[i]] = Counter(c+1);
}
}
i -= 1;
} SA[0] = Index(n-1);
for i in 1..n { match SA[i] {
Index(ind) => {
let j = ind-1;
if j+1<n && t[j]>t[j+1] || (t[j]==t[j+1] && !SA[j].is_index()) { let mut lfentry = tp[j];
while let Index(_) = SA[lfentry] {lfentry += 1;} SA[lfentry] = Index(j);
}
},
Counter(1) => { SA[tp[i]] = Index(i);
},
Counter(c) if c>1 => {
SA[tp[i] + c-1] = Index(i);
SA[i] = Counter(c-1);
},
_ => {}, } }
tp
}
fn main() {
let t0 = "2113311331210".as_bytes();
let n= t0.len();
let mut t = [0u8;256];
t[0..n].copy_from_slice(&t0);
let mut sa = [0usize;256];
let tp = rename(&mut t, &mut sa, 13);
println!("Tprime: {:?}",&tp[..n]);
}
#[derive(PartialEq,Eq,Copy,Clone,Debug)]
enum SAEntry
{
Index(usize),
Counter(usize), }impl Default for SAEntry {
fn default() -> Self { SAEntry::Counter(0) }
}impl SAEntry {
fn is_index(&self) -> bool {
if let &SAEntry::Index(_) = self {true} else {false}
}
fn is_empty(&self) -> bool {
if let &SAEntry::Counter(0) = self {true} else {false}
}
}