-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgmo-node.js
More file actions
130 lines (107 loc) · 2.77 KB
/
gmo-node.js
File metadata and controls
130 lines (107 loc) · 2.77 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//trumpet is trombone
let players = [
[0, 1, 3], //fl
[1, 3, 4], //ob
[0], //kl
[2, 4], //bn
[2], //hn
// [], //tpt
[0, 1, 3, 5], //tn or tpt
// tim
// perc
// fol
// hl
// hr
[0, 1, 2, 3, 4], //vn or vnII
[0, 1, 2, 3, 4], //vn
[0, 3], //va
[5], //vc
[4], //cb
]
let playernames = [
"fl",
"ob",
"kl",
"bn",
"hn",
"tn or tpt",
"vn",
"vII",
"va",
"vc",
"cb",
]
require('get-stdin')().then ( music => {
let rawbars = music
.split('%bn')
.map(x=>x.trim())
//ignore everything before first %bn
.slice(1)
let bars = rawbars
.map(m => m.split(/\n+/)
.map(b => (b+"%").slice(0, b.indexOf('%')))
.join(''))
.map(b => b.split('|').map(k => k.trim()))
.map(k => k.slice(6, 23))
let nonemptybars = bars
.map(m => m.map(b => b.split(/\s+/).some(w => !w.toLowerCase().startsWith('r'))))
.map(b => [
...b.slice(0,5),
b[5] || b[6],
b[12] , b[13],
...b.slice(14)
])
function cross(choices){
if(choices.length == 1) return choices[0].map(c => [c])
const subsolution = cross(choices.slice(1))
return [].concat(...(choices[0].map(c => subsolution.map(s => [c, ...s]))))
}
const uniq = arr => Array.from(new Set(arr))
function assign2(need){
let best_diff = Infinity
let best = []
for(let assignment of cross(need)){
const u = uniq(assignment).length
if(u === assignment.length) return assignment
if(assignment.length - u < best_diff) {
best_diff = assignment.length - u
best = assignment
}
}
console.log('%Error: no solution found. Returning best guess.')
return best
}
// console.log(nonemptybars.map(assign))
function solve(bar){
let need = []
let used = []
bar.forEach((ne, i) =>{
if(!ne) return;
// console.log(i)
need.push(players[i])
used.push(i)
})
// need is array of arrays of keyboard players needed
// console.log('need', need)
let sol = assign2(need)
let ret = [...bar]
if (sol) sol.forEach((p,i) => ret[used[i]] = p)
return sol && ret
}
// solve(nonemptybars[1])
let sol = nonemptybars
.map(solve)
.forEach((bar, i) => {
// tex += '\nbarnumber: '+ b.barnumber
// if(bar){
let ret = ['rest','rest','rest','rest','rest','rest']
playernames.forEach((name, i) => {
ret[bar[i]] = name
})
console.log( '%parts:', ret.map((p, i) => p).join(' % '))
// } else {
let numparts=nonemptybars[i].reduce((a,b)=>a+b,0)
if(numparts>6) console.log('%Error: too many parts', numparts )
// }
})
}).catch(e=>console.log(e))