Created
February 5, 2026 21:59
-
-
Save lerouxb/29b0a430aa6a57d447ca1cb43ee52c0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Checks if two numbers are relatively prime (coprime). | |
| * @param {number} k - The number of pulses. | |
| * @param {number} n - The total number of steps. | |
| * @returns {boolean} - True if GCD is 1, otherwise false. | |
| */ | |
| function areRelativelyPrime(k, n) { | |
| // Helper function using the Euclidean Algorithm to find GCD | |
| function gcd(a, b) { | |
| while (b !== 0) { | |
| let temp = b; | |
| b = a % b; | |
| a = temp; | |
| } | |
| return a; | |
| } | |
| // Two numbers are relatively prime if their GCD is 1 | |
| return gcd(k, n) === 1; | |
| } | |
| /** | |
| * Generates a Euclidean rhythm pattern. | |
| * @param {number} k - Number of pulses (onsets). | |
| * @param {number} n - Total number of steps (length). | |
| * @returns {number[]} Array of 1s and 0s representing the rhythm. | |
| */ | |
| function generateEuclidean(k, n) { | |
| // 1. Initial state: k groups of [1] and n-k groups of [0] | |
| let groups = []; | |
| for (let i = 0; i < n; i++) { | |
| groups.push(i < k ? [1] : [0]); | |
| } | |
| // 2. Iteratively distribute the remainder groups into the leading groups | |
| let l = n - k; // Number of zeros initially | |
| let m = k; // Number of ones initially | |
| while (l > 0 && m > 0) { | |
| let numToMove = Math.min(m, l); | |
| for (let i = 0; i < numToMove; i++) { | |
| // Concatenate the last group into the i-th group | |
| groups[i] = groups[i].concat(groups.pop()); | |
| } | |
| // Update counts based on what was moved | |
| if (m > l) { | |
| m = l; | |
| l = m - l; // This logic follows the recursive Euclidean structure | |
| } else { | |
| l = l - m; | |
| } | |
| // Re-calculating remaining groups for the next iteration | |
| m = numToMove; | |
| l = groups.length - m; | |
| // Exit when there is only one type of group left or no remainder | |
| if (l <= 1) break; | |
| } | |
| // 3. Flatten the nested arrays into a single sequence | |
| return groups.flat(); | |
| } | |
| let total = 0; | |
| console.log('std::vector<std::vector<std::bool>> euclideanRhythms {'); | |
| console.log(' // none'); | |
| console.log(' { 0 },'); | |
| console.log(' // four to the floor'); | |
| console.log(' { 1 },'); | |
| for (let n = 1; n <= 16; n++) { | |
| for (let k = 1; k < n; k++) { | |
| if (areRelativelyPrime(k, n)) { | |
| const pattern = generateEuclidean(k, n); | |
| console.log(` // k=${k}, n=${n}`); | |
| console.log(` { ${pattern.join(', ')} },`); | |
| total++; | |
| } | |
| } | |
| } | |
| console.log('};') | |
| console.log(`Total: ${total}`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment