Code for billiard scales: Difference between revisions

Inthar (talk | contribs)
Inthar (talk | contribs)
Line 502: Line 502:
//! 3. For each region, trace a trajectory and record which coordinate changes
//! 3. For each region, trace a trajectory and record which coordinate changes
//! 4. The sequence of changes (0=L, 1=m, 2=s) forms the scale word
//! 4. The sequence of changes (0=L, 1=m, 2=s) forms the scale word
//!
//! # Examples
//!
//! ```
//! use ternary::billiard::billiard_scales;
//!
//! // Generate all billiard scales with signature 5L 2m 2s
//! let scales = billiard_scales(5, 2, 2);
//! assert!(!scales.is_empty());
//!
//! // Each scale has the correct number of steps
//! for scale in &scales {
//!    assert_eq!(scale.len(), 9);  // 5 + 2 + 2 = 9 notes
//! }
//! ```
//!
//! # Properties
//! # Properties
//!
//!
Line 566: Line 550:


/// Rotate a scale word left by `degree` positions (change mode).
/// Rotate a scale word left by `degree` positions (change mode).
///
/// # Examples
///
/// ```
/// use ternary::words::rotate;
///
/// let lydian = vec![0, 0, 0, 1, 0, 0, 1];
/// let mixolydian = rotate(&lydian, 1);  // Rotate left by 1
/// assert_eq!(mixolydian, vec![0, 0, 1, 0, 0, 1, 0]);
/// ```
pub fn rotate<T: std::clone::Clone>(slice: &[T], degree: usize) -> Vec<T> {
pub fn rotate<T: std::clone::Clone>(slice: &[T], degree: usize) -> Vec<T> {
     let degree = degree % slice.len();
     let degree = degree % slice.len();
Line 586: Line 560:


/// The lexicographically least mode of a word (where the letters are in their usual order).
/// The lexicographically least mode of a word (where the letters are in their usual order).
///
/// # Examples
///
/// ```
/// use ternary::words::least_mode;
///
/// let ionian = vec![0, 0, 1, 0, 0, 0, 1]; // LLsLLLs
/// let lydian = vec![0, 0, 0, 1, 0, 0, 1]; // LLLsLLs (lexicographically least mode of diatonic)
/// assert_eq!(least_mode(&ionian), lydian)
/// ```
pub fn least_mode(scale: &[Letter]) -> Vec<Letter> {
pub fn least_mode(scale: &[Letter]) -> Vec<Letter> {
     rotate(scale, booth(scale))
     rotate(scale, booth(scale))
Line 847: Line 811:
/// * `b` - Number of m (medium) steps
/// * `b` - Number of m (medium) steps
/// * `c` - Number of s (small) steps
/// * `c` - Number of s (small) steps
///
/// # Examples
///
/// ```
/// use ternary::billiard::billiard_scales;
///
/// // Generate billiard scales for 5L 2m 2s
/// let scales = billiard_scales(5, 2, 2);
/// assert!(!scales.is_empty());
///
/// // All scales are in canonical form (sorted)
/// for scale in &scales {
///    assert_eq!(scale.iter().filter(|&&x| x == 0).count(), 5);  // 5 L steps
/// }
/// ```
///
/// # Returns
/// # Returns
///
///