1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
extern crate smallvec;
use smallvec::SmallVec;
pub fn euclidian_rythm(p: &mut [u8], pulses: usize) -> Result<(), &'static str> {
let steps = p.len();
let mut pattern = SmallVec::from_slice(p);
pattern.clear();
if pulses > steps {
return Err("more pulses than steps.");
}
let mut divisor = steps - pulses;
let mut level = 0;
let mut counts = SmallVec::<[usize; 64]>::new();
let mut remainders = SmallVec::<[usize; 64]>::new();
remainders.push(pulses);
loop {
counts.push(divisor / remainders[level]);
let r = remainders[level];
remainders.push(divisor % r);
divisor = remainders[level];
level += 1;
if remainders[level] <= 1 {
break;
}
}
counts.push(divisor);
fn build(
counts: &[usize],
pattern: &mut SmallVec<[u8; 64]>,
remainders: &[usize],
level: isize,
) {
if level == -1 {
pattern.push(0);
} else if level == -2 {
pattern.push(1);
} else {
for _ in 0..counts[level as usize] {
build(counts, pattern, remainders, level - 1);
}
if remainders[level as usize] != 0 {
build(counts, pattern, remainders, level - 2);
}
}
}
build(
counts.as_slice(),
&mut pattern,
remainders.as_slice(),
level as isize,
);
let index_first_one = pattern.iter().position(|&x| x == 1).unwrap();
pattern.rotate_left(index_first_one);
p.copy_from_slice(&pattern);
return Ok(());
}
#[cfg(test)]
mod tests {
use euclidian_rythm;
#[test]
fn it_works() {
let mut pattern = [0 as u8; 8];
let pulses = 4;
euclidian_rythm(&mut pattern, pulses).unwrap();
println!("{:?}", pattern);
let mut pattern = [0 as u8; 9];
let pulses = 3;
euclidian_rythm(&mut pattern, pulses).unwrap();
println!("{:?}", pattern);
let mut pattern = [0 as u8; 12];
let pulses = 7;
euclidian_rythm(&mut pattern, pulses).unwrap();
println!("{:?}", pattern);
let mut pattern = [0 as u8; 13];
let pulses = 5;
euclidian_rythm(&mut pattern, pulses).unwrap();
println!("{:?}", pattern);
let mut pattern = [0 as u8; 31];
let pulses = 7;
euclidian_rythm(&mut pattern, pulses).unwrap();
println!("{:?}", pattern);
}
}