pub fn generate(groupings: &[usize]) -> Vec<usize> {
if groupings.is_empty() {
return vec![];
}
let mut accents = Vec::with_capacity(groupings.len());
let mut position = 0;
for &group_size in groupings {
accents.push(position);
position += group_size;
}
accents
}
pub fn rachenitsa() -> Vec<usize> {
generate(&[2, 2, 3])
}
pub fn kopanitsa() -> Vec<usize> {
generate(&[2, 2, 3, 2, 2])
}
pub fn kalamatianos() -> Vec<usize> {
generate(&[3, 2, 2])
}
pub fn aksak_9_8() -> Vec<usize> {
generate(&[2, 2, 2, 3])
}
pub fn additive_meter_rotations(groupings: &[usize]) -> Vec<Vec<usize>> {
if groupings.is_empty() {
return vec![];
}
let mut rotations = Vec::with_capacity(groupings.len());
for rotation_idx in 0..groupings.len() {
let mut rotated = Vec::with_capacity(groupings.len());
for i in 0..groupings.len() {
let idx = (rotation_idx + i) % groupings.len();
rotated.push(groupings[idx]);
}
rotations.push(generate(&rotated));
}
rotations
}
pub fn additive_meter_length(groupings: &[usize]) -> usize {
groupings.iter().sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_additive_meter_basic() {
let pattern = generate(&[2, 2, 3]);
assert_eq!(pattern, vec![0, 2, 4]);
}
#[test]
fn test_additive_meter_empty() {
let pattern = generate(&[]);
assert_eq!(pattern, vec![]);
}
#[test]
fn test_additive_meter_single_group() {
let pattern = generate(&[5]);
assert_eq!(pattern, vec![0]);
}
#[test]
fn test_additive_meter_various_groupings() {
assert_eq!(generate(&[3, 2]), vec![0, 3]);
assert_eq!(generate(&[2, 3, 2]), vec![0, 2, 5]);
assert_eq!(generate(&[3, 3, 2]), vec![0, 3, 6]);
}
#[test]
fn test_rachenitsa() {
let pattern = rachenitsa();
assert_eq!(pattern, vec![0, 2, 4]);
assert_eq!(pattern.len(), 3); }
#[test]
fn test_kopanitsa() {
let pattern = kopanitsa();
assert_eq!(pattern, vec![0, 2, 4, 7, 9]);
assert_eq!(pattern.len(), 5); }
#[test]
fn test_kalamatianos() {
let pattern = kalamatianos();
assert_eq!(pattern, vec![0, 3, 5]);
assert_eq!(pattern.len(), 3); }
#[test]
fn test_aksak_9_8() {
let pattern = aksak_9_8();
assert_eq!(pattern, vec![0, 2, 4, 6]);
assert_eq!(pattern.len(), 4); }
#[test]
fn test_additive_meter_length() {
assert_eq!(additive_meter_length(&[2, 2, 3]), 7);
assert_eq!(additive_meter_length(&[2, 2, 3, 2, 2]), 11);
assert_eq!(additive_meter_length(&[3, 2, 2]), 7);
assert_eq!(additive_meter_length(&[2, 2, 2, 3]), 9);
}
#[test]
fn test_additive_meter_length_empty() {
assert_eq!(additive_meter_length(&[]), 0);
}
#[test]
fn test_additive_meter_rotations() {
let rotations = additive_meter_rotations(&[2, 2, 3]);
assert_eq!(rotations.len(), 3);
assert_eq!(rotations[0], vec![0, 2, 4]);
assert_eq!(rotations[1], vec![0, 2, 5]);
assert_eq!(rotations[2], vec![0, 3, 5]);
}
#[test]
fn test_additive_meter_rotations_empty() {
let rotations = additive_meter_rotations(&[]);
assert_eq!(rotations, Vec::<Vec<usize>>::new());
}
#[test]
fn test_additive_meter_rotations_single() {
let rotations = additive_meter_rotations(&[5]);
assert_eq!(rotations.len(), 1);
assert_eq!(rotations[0], vec![0]);
}
#[test]
fn test_all_patterns_start_at_zero() {
assert_eq!(rachenitsa()[0], 0);
assert_eq!(kopanitsa()[0], 0);
assert_eq!(kalamatianos()[0], 0);
assert_eq!(aksak_9_8()[0], 0);
}
#[test]
fn test_patterns_are_sorted() {
let patterns = vec![rachenitsa(), kopanitsa(), kalamatianos(), aksak_9_8()];
for pattern in patterns {
let mut sorted = pattern.clone();
sorted.sort_unstable();
assert_eq!(pattern, sorted);
}
}
#[test]
fn test_rachenitsa_vs_kalamatianos() {
let rach = rachenitsa(); let kalam = kalamatianos();
assert_ne!(rach, kalam);
assert_eq!(rach.len(), kalam.len());
assert_eq!(additive_meter_length(&[2, 2, 3]), 7);
assert_eq!(additive_meter_length(&[3, 2, 2]), 7);
}
#[test]
fn test_additive_meter_with_larger_groups() {
let pattern = generate(&[4, 3, 5]);
assert_eq!(pattern, vec![0, 4, 7]);
assert_eq!(additive_meter_length(&[4, 3, 5]), 12);
}
#[test]
fn test_additive_meter_all_twos() {
let pattern = generate(&[2, 2, 2, 2]);
assert_eq!(pattern, vec![0, 2, 4, 6]);
}
#[test]
fn test_additive_meter_rotations_kopanitsa() {
let rotations = additive_meter_rotations(&[2, 2, 3, 2, 2]);
assert_eq!(rotations.len(), 5);
for rotation in &rotations {
assert_eq!(rotation.len(), 5);
}
for rotation in &rotations {
assert_eq!(rotation[0], 0);
}
}
#[test]
fn test_complex_meter_13_8() {
let pattern = generate(&[3, 2, 2, 3, 3]);
assert_eq!(pattern, vec![0, 3, 5, 7, 10]);
assert_eq!(additive_meter_length(&[3, 2, 2, 3, 3]), 13);
}
}