census.rs

2.6 kB · rust · 114 lines

1use crate::rows::{Row, Sheet, CEILING};23pub const WINDOWS: [usize; 3] = [1_000, 10_000, 100_000];4pub const CHAMPIONS: usize = 20;5pub const MISSES: usize = 30;67pub struct Census {8    pub counts: Vec<u32>,9    pub incidences: u64,10    pub repeats: u64,11    pub low: u64,12}1314pub struct Band {15    pub first: usize,16    pub last: usize,17    pub missed: usize,18}1920impl Band {21    pub fn width(&self) -> usize {22        self.last - self.first + 123    }24    pub fn density(&self) -> f64 {25        self.missed as f64 / self.width() as f6426    }27}2829pub fn build(sheet: &Sheet) -> Census {30    let mut counts = vec![0u32; CEILING as usize + 1];31    let mut incidences = 0u64;32    let mut repeats = 0u64;33    let mut low = 0u64;34    for row in &sheet.rows {35        for &term in &row.written {36            counts[term as usize] += 1;37            incidences += 1;38        }39        repeats += row.repeats as u64;40        low += row.low as u64;41    }42    Census {43        counts,44        incidences,45        repeats,46        low,47    }48}4950pub fn split(census: &Census, window: usize) -> (usize, usize, usize) {51    let mut never = 0;52    let mut once = 0;53    let mut many = 0;54    for &count in &census.counts[1..=window] {55        match count {56            0 => never += 1,57            1 => once += 1,58            _ => many += 1,59        }60    }61    (never, once, many)62}6364pub fn champions(census: &Census, take: usize) -> Vec<(usize, u32)> {65    let mut all: Vec<(usize, u32)> = census66        .counts67        .iter()68        .enumerate()69        .skip(1)70        .map(|(value, &count)| (value, count))71        .collect();72    all.sort_by(|left, right| right.1.cmp(&left.1).then(left.0.cmp(&right.0)));73    all.truncate(take);74    all75}7677pub fn misses(census: &Census, take: usize) -> Vec<usize> {78    census79        .counts80        .iter()81        .enumerate()82        .skip(1)83        .filter(|(_, &count)| count == 0)84        .map(|(value, _)| value)85        .take(take)86        .collect()87}8889pub fn bands(census: &Census) -> Vec<Band> {90    let mut out = Vec::new();91    let mut first = 1usize;92    while first <= CEILING as usize {93        let last = (first * 10 - 1).min(CEILING as usize);94        let missed = census.counts[first..=last]95            .iter()96            .filter(|&&count| count == 0)97            .count();98        out.push(Band {99            first,100            last,101            missed,102        });103        first *= 10;104    }105    out106}107108pub fn writers<'a>(sheet: &'a Sheet, value: i128) -> Vec<&'a Row> {109    sheet110        .rows111        .iter()112        .filter(|row| row.written.binary_search(&value).is_ok())113        .collect()114}