For example, these are expected outputs:
3: 2, 1
4: 4
5: 4, 1
6: 4, 2
7: 4, 2, 1
8: 8
9: 8, 1
...
20: 16, 4
...
25: 16, 8, 1
...
36: 32, 4
...
50: 32, 16, 2
Up to the max of 32 being the largest subunit. So then we get larger:
100: 32, 32, 32, 4
...
201: 32, 32, 32, 32, 32, 32, 8, 1
...
What is the equation / algorithm to implement this most optimally in JavaScript? By optimal I mean the fastest performance, or fewest primitive steps for example, with the least amount of temporary variables, etc. I feel like my solution below is a "brute force" approach which lacks elegance and it seems like it could be optimized somehow. Ideally there would be no Math.floor
or division as well, if possible to use some sort of bit magic.
log(20)
log(25)
log(36)
log(50)
log(100)
log(200)
function log(n) {
console.log(generate_numbers(n).join(', '))
}
function generate_numbers(n) {
const chunks = count_chunks(n)
const sum = chunks.reduce((m, i) => m + i, 0)
const result = new Array(sum)
const values = [ 1, 2, 4, 8, 16, 32 ]
let i = chunks.length
let j = 0
while (i--) {
let x = chunks[i]
while (x--) {
result[j++] = values[i]
}
}
return result
}
function count_chunks(n) {
let chunks = [0, 0, 0, 0, 0, 0]
if (n >= 32) {
let i = Math.floor(n / 32)
chunks[5] = i
n = n - (i * 32)
}
if (n >= 16) {
chunks[4] = 1
n = n - 16
}
if (n >= 8) {
chunks[3] = 1
n = n - 8
}
if (n >= 4) {
chunks[2] = 1
n = n - 4
}
if (n >= 2) {
chunks[1] = 1
n = n - 2
}
if (n >= 1) {
chunks[0] = 1
}
return chunks
}
generate_numbers
? The result ofcount_chunks
? And is the order of the numbers important or could they also be ascending? \$\endgroup\$n >> bitpos
times.) e.g.(-x) & (x)
to isolate the lowest set bit.(x-1) & (x)
to clear the lowest set bit. Repeat until no low bits are set:x & ((1<<bitpos) - 1)
\$\endgroup\$