-
Notifications
You must be signed in to change notification settings - Fork 13
/
euclidian_rhythm.go
66 lines (61 loc) · 1.25 KB
/
euclidian_rhythm.go
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
package theory
func EuclidianRhythm(n, over int) []bool {
result := make([]bool, over)
if n == 0 {
return result
}
// Bjorklunds Algorithm
// Generate the first buckets
// e.g. [[1], [1], [1], [1], [1], [0], [0], ...., [0]]
//
nrOfBuckets := over
buckets := make([][]bool, nrOfBuckets)
left_to_distribute := 0
for i := 0; i < nrOfBuckets; i++ {
v := i < n
buckets[i] = []bool{v}
if !v {
left_to_distribute++
}
}
ix := 0
for left_to_distribute != 0 {
if ix >= nrOfBuckets-1 || !buckets[ix][0] {
ix = 0
} else {
bix := nrOfBuckets - 1
buckets[ix] = mergeBuckets(buckets[ix], buckets[bix])
buckets[bix] = []bool{}
ix++
nrOfBuckets--
left_to_distribute--
// see if there are more buckets left to distribute
if left_to_distribute == 0 {
ix = 0
l := len(buckets[0])
for j := 1; j < nrOfBuckets; j++ {
if len(buckets[j]) != l {
left_to_distribute++
}
}
if left_to_distribute == 1 { // only one remainder
break
}
}
}
}
ix = 0
for i := 0; i < nrOfBuckets; i++ {
for j := 0; j < len(buckets[i]); j++ {
result[ix] = buckets[i][j]
ix++
}
}
return result
}
func mergeBuckets(b1, b2 []bool) []bool {
for _, v := range b2 {
b1 = append(b1, v)
}
return b1
}