use crate::model::{Note, RoxChart};
use std::collections::HashMap;
pub fn polyphony(chart: &RoxChart) -> HashMap<u32, u32> {
if chart.notes.is_empty() {
return HashMap::new();
}
let mut distribution = HashMap::new();
let mut current_time: Option<i64> = None;
let mut current_cluster_size = 0;
let mut refs: Vec<&Note> = chart.notes.iter().collect();
refs.sort_by_key(|n| n.time_us);
for note in refs {
if note.is_mine() {
continue;
}
if Some(note.time_us) != current_time {
if current_cluster_size > 0 {
*distribution.entry(current_cluster_size).or_insert(0) += 1;
}
current_time = Some(note.time_us);
current_cluster_size = 0;
}
current_cluster_size += 1;
}
if current_cluster_size > 0 {
*distribution.entry(current_cluster_size).or_insert(0) += 1;
}
distribution
}
pub fn lane_balance(chart: &RoxChart) -> Vec<u32> {
let mut counts = vec![0; chart.key_count() as usize];
for note in &chart.notes {
if note.is_mine() {
continue;
}
let col = note.column as usize;
if col < counts.len() {
counts[col] += 1;
}
}
counts
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::Note;
#[test]
fn test_lane_balance() {
let mut chart = RoxChart::new(4);
chart.notes.push(Note::tap(0, 0));
chart.notes.push(Note::tap(100, 0));
chart.notes.push(Note::tap(200, 3));
let balance = lane_balance(&chart);
assert_eq!(balance, vec![2, 0, 0, 1]);
}
#[test]
fn test_polyphony() {
let mut chart = RoxChart::new(4);
chart.notes.push(Note::tap(0, 0));
chart.notes.push(Note::tap(100, 0));
chart.notes.push(Note::tap(100, 1));
chart.notes.push(Note::tap(200, 0));
chart.notes.push(Note::tap(200, 1));
chart.notes.push(Note::tap(200, 2));
chart.notes.push(Note::tap(300, 3));
let dist = polyphony(&chart);
assert_eq!(dist.get(&1), Some(&2)); assert_eq!(dist.get(&2), Some(&1)); assert_eq!(dist.get(&3), Some(&1)); assert_eq!(dist.get(&4), None);
}
}