Let's say I have an integer I and want to get the count of 1s in its binary form.
I am currently using the following code.
Number(i.toString(2).split("").sort().join("")).toString().length;
Is there a faster way to do this? I am thinking about using bitwise operators. Any thoughts?
NOTE: i is within the 32-bit limitation.
You can use a strategy from this collection of Bit Twiddling Hacks:
function bitCount (n) {
n = n - ((n >> 1) & 0x55555555)
n = (n & 0x33333333) + ((n >> 2) & 0x33333333)
return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24
}
console.log(bitCount(0xFF)) //=> 8
Note that the above strategy only works for 32-bit integers (a limitation of bitwise operators in JavaScript).
A more general approach for larger integers would involve counting 32-bit chunks individually (thanks to harold for the inspiration):
function bitCount (n) {
var bits = 0
while (n !== 0) {
bits += bitCount32(n | 0)
n /= 0x100000000
}
return bits
}
function bitCount32 (n) {
n = n - ((n >> 1) & 0x55555555)
n = (n & 0x33333333) + ((n >> 2) & 0x33333333)
return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24
}
console.log(bitCount(Math.pow(2, 53) - 1)) //=> 53
You could also use a regular expression:
function bitCount (n) {
return n.toString(2).match(/1/g).length
}
console.log(bitCount(0xFF)) //=> 8
A recursive very nice but slow way:
function count1(n, accumulator=0) {
if (n === 0) {
return accumulator
}
return count1(n/2, accumulator+(n&1))
}
console.log(count1(Number.MAX_SAFE_INTEGER));
But if you want a very fast one (faster than T.J. Crowder answer)):
count1s=(n)=>n.toString(2).replace(/0/g,"").length
console.log(count1s(Number.MAX_SAFE_INTEGER));
Note: some of the other solutions do not work with bit integers (> 32 bit)
these two do!
Now, if we consider only 32 bit numbers, the fastest way is this:
function count1s32(i) {
var count = 0;
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0f0f0f0f;
i = i + (i >> 8);
i = i + (i >> 16);
count += i & 0x3f;
return count;
}
console.log(count1s32(0xffffffff));
https://jsperf.com/count-1/1
53 bit comparison:
32 bit comparison:
Benchmark here! (since jsperf is often down).
function log(data) {
document.getElementById("log").textContent += data + "\n";
}
benchmark = (() => {
time_function = function(ms, f, num) {
var z;
var t = new Date().getTime();
for (z = 0;
((new Date().getTime() - t) < ms); z++) f(num);
return (z / ms)
} // returns how many times the function was run in "ms" milliseconds.
// two sequential loops
count1s = (n) => n.toString(2).replace(/0/g, "").length
// three loops and a function.
count1j = (n) => n.toString(2).split('').filter(v => +v).length
/* Excluded from test because it's too slow :D
function count1(n, accumulator=0) {
if (n === 0) {
return accumulator
}
return count1(n / 2, accumulator + (n & 1))
}
*/
function countOnes(i) {
var str = i.toString(2);
var n;
var count = 0;
for (n = 0; n < str.length; ++n) {
if (str[n] === "1") {
++count;
}
}
return count;
} // two sequential loops ( one is the toString(2) )
function count1sb(num) {
i = Math.floor(num / 0x100000000);
// if (i > 0) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0f0f0f0f;
i = i + (i >> 8);
i = i + (i >> 16);
count = i & 0x3f;
i = num & 0xffffffff;
// }
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0f0f0f0f;
i = i + (i >> 8);
i = i + (i >> 16);
count += i & 0x3f;
return count;
}
function benchmark() {
function compare(a, b) {
if (a[1] > b[1]) {
return -1;
}
if (a[1] < b[1]) {
return 1;
}
return 0;
}
funcs = [
[count1s, 0],
[count1j, 0],
[count1sb, 0],
[countOnes, 0]
];
funcs.forEach((ff) => {
console.log("Benchmarking: " + ff[0].name);
ff[1] = time_function(2500, ff[0], Number.MAX_SAFE_INTEGER);
console.log("Score: " + ff[1]);
})
return funcs.sort(compare);
}
return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();
console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());
<textarea cols=80 rows=30 id="log"></textarea>
The benchmark will run for 10s.
Doing n = n & (n - 1) you removing last 1 bit in the number.
According to this, you can use the following algorithm:
function getBitCount(n) {
var tmp = n;
var count = 0;
while (tmp > 0) {
tmp = tmp & (tmp - 1);
count++;
}
return count;
}
console.log(getBitCount(Math.pow(2, 10) -1));
Given that you're creating, sorting, and joining an array, if it's literally faster you want, you're probably better off doing it the boring way:
console.log(countOnes(8823475632));
function countOnes(i) {
var str = i.toString(2);
var n;
var count = 0;
for (n = 0; n < str.length; ++n) {
if (str[n] === "1") {
++count;
}
}
return count;
}
(Use str.charAt(n) instead of str[n] if you need to support obsolete browsers.)
It's not as l33t or concise, but I bet it's faster it's much faster:
...and similarly on Firefox, IE11 (IE11 to a lesser degree).
Below works fine with any number:
var i=8823475632,count=0;while (i=Math.floor(i)) i&1?count++:0,i/=2
console.log(count); //17
change the i to the value you want or wrap it as a function
if integer is within 32-bit , below works
var i=10,count=0;while (i) i&1?count++:0,i>>=1
if you want to use an absolute one liner solution you can have a look at this.
countBits = n => n.toString(2).split('0').join('').length;
1.Here n.toString(2) converts n into binary string
2.split('0') makes array out of the binary string splitting only at
0's and hence returning an array of only 1 present in binary of n
3.join('') joins all one and making a string of 1s
4.length finds length of the string actually counting number of 1's in n.
A few more "fun" 1-liners:
Recursive: count each bit recursively until there's no more bits set
let f = x => !x ? 0 : (x & 1) + f(x >>= 1);
Functional: split the base 2 string of x and return the accumulated length of bits set
g = x => x.toString(2).split('0').map(bits => bits.length).reduce((a, b) => a + b);
Keeps on checking if last bit is 1, and then removing it. If it finds last bit is one, it adds it to its result.
Math.popcount = function (n) {
let result = 0;
while (n) {
result += n % 2;
n = n >>> 1;
};
return result;
};
console.log(Math.popcount(0b1010));
For 64 bits, you can represent the number as two integers, the first is the top 32 digits, and the second is the bottom 32. To count number of ones in 64 bits, you can seperate them into 2, 32 bit integers, and add the popcount of the first and second.
You can skip Number, sort and the second toString. Use filter to only consider the 1s (a truthy value) in the array then retrieve how many got through with length.
i.toString(2).split('').filter(v => +v).length
Simple solution if you just want to count number of bit!
const integer = Number.MAX_SAFE_INTEGER;
integer.toString(2).split("").reduce((acc,val)=>parseInt(acc)+parseInt(val),0);
Regex
const bitCount = (n) => (n.toString(2).match(/1/g) || []).length;
Bitwise AND, Right Shift
function bitCount(n) {
let count = 0;
while(n) {
count += n & 1;
n >>= 1;
}
return count;
}
Brian Kernighan algorithm
function bitCount(n) {
let count = 0;
while(n) {
n &= (n-1);
count ++;
}
return count;
}
test:
bitCount(0) // 0
bitCount(1) // 1
bitCount(2) // 1
bitCount(3) // 2
Related
let power2 = (x,n) => {
if(n == 0) return 1;
let temp = power2(x,n/2);
if(n%2 == 1) return temp * temp * x;
return temp*temp;
}
console.log(power2(4,3));
This method has less nodes and time complexity but its giving wrong output
The problem with the original code was the fact that n / 2 will result in a real number when you need it to be treated as an integer. Bitwise operation are always performed on integers so n >> 1 will correctly yield an integer. The same goes with modulo which converts the number to an integer first that's why it worked correctly in your code.
let power2 = (x, n) => {
if (n === 0) return 1;
const temp = power2(x, (n >> 1));
if (n % 2 === 1) return temp * temp * x;
return temp * temp;
}
console.log(power2(4, 3));
If you need custom integer power function, based on recursion, consider this snippet:
// Custom pow
const myPow = (n, i) => i > 0 ? myPow(n, i - 1) * n : 1;
// Test
console.log(myPow(4, 3));
Here is my solution
export function removeNb (n:number):number[][] {
const total = n * (n+1) / 2;
for(let a = n; a > 1; a--){
for(let b = a-1 ;b > 1 ; b--){
if(total - b - a === b*a){
return [[b,a],[a,b]]
}
}
}
return []
}
The problem is this:
A friend of mine takes the sequence of all numbers from 1 to n (where
n > 0).
Within that sequence, he chooses two numbers, a and b.
He says that the product of a and b should be equal to the sum of all
numbers in the sequence, excluding a and b.
Given a number n, could you tell me the numbers he excluded from the
sequence?
The function takes the parameter: n (n is always strictly greater than
0) and returns an array of arrays.
The test cases are as follows:
removeNb(26); //[[15,21],[21,15]]
removeNb(101); //[[55,91],[91,55]]
removeNb(102); //[[70,73],[73,70]]
removeNb(110); //[[70,85],[85,70]]
Update
As Ike mentioned the previous solution doesn't take in account the fact that a and b both need to be less or equal to n so the solution should be updated like this : (b needs to be less then n, ie (total - a) / (a + 1) <= n ie (total - n) / (n + 1) <= a)
function removeNb(n: number) {
const total = n * (n + 1) / 2;
const t: [number, number][] = [];
for (let a = Math.ceil((total - n) / (n + 1)); a * a < total; a++) {
const b = (total - a) / (a + 1)
if (!(b % 1)) t.push([a,b],...(a === b ? [] : [[b,a]]))
}
return t
}
With a bit of maths we can check that tatal - a - b = a * b is equivalent to (total - a) / (a + 1) = b so we can deduce b from a and just check if it is an integer.
Also since a and b are exchangeable we can require b to be greater or equal a i.e (total - a) / (a + 1) >= a <=> total >= a * (a + 2) so we can require a² < total.
So your function can be optimized this way:
function removeNb(n: number) {
const total = n * (n + 1) / 2;
const t: [number, number][] = [];
for (let a = 1; a * a < total; a++) {
const b = (total - a) / (a + 1)
if (!(b % 1)) t.push([a,b],...(a === b ? [] : [[b,a]]))
}
return t
}
I have written the code of this problem but it works for only 70% of the test cases. I can't figure out what is wrong with it. Please help.
Problem:-
Find the number of ways that a given integer, X, can be expressed as the sum of the Nth powers of unique, natural numbers in the range of [1,25] both inclusive.
Hint:-
The answer will be (1^2 + 3^2).
My code is not working for x = 100 and n = 2. The output should be 3 but it returns 33.
let x = 100;
let n = 2;
let num = 0;
let index = 1;
function power(x, n, num, index, ways = 0) {
if (x === num) {
return 1;
}
if (x < num) {
return 0;
}
for (let i = index; i <= 25; i++) {
ways += power(x, n, (num + ((i) ** n)), index + 1);
}
return ways;
}
console.log(power(x, n, num, index));
Your logic is almost right. But you're not properly removing duplicate values and ending up including things like 9^2 + 3^2 + 3^2 + 1^2 or 5^2 + 5^2 + 5^2 + 4^2 + 3^2.
You need to change the recursive index you pass. You shouldn't use your index parameter but your loop iterator, i:
let x = 100;
let n = 2;
let num = 0;
let index = 1;
function power(x, n, num, index, ways = 0) {
if (x === num) {
return 1;
}
if (x < num) {
return 0;
}
for (let i = index; i <= 25; i++) {
// ways += power(x, n, (num + ((i) ** n)), index + 1);
// v-^
ways += power(x, n, (num + ((i) ** n)), i + 1);
}
return ways;
}
console.log(power(x, n, num, index));
I figured this out fairly quickly by writing my own version of the function from scratch, and getting the exact same wrong result. I added some logging and realized the problem and was able to spot it quickly. This translated easily to your code.
But I think my function is cleaner, so I'm including it here. It does much the same logic, but in a cleaner functional manner:
const range = (lo, hi) =>
Array .from ({length: hi - lo + 1}, (_, i) => i + lo)
const sum = (ns) =>
ns .reduce ((a, b) => a + b, 0)
const countPowerSums = (n, p, i = 1) =>
n < 0
? 0
: n == 0
? 1
: sum (range (i, 25) .map (b => countPowerSums (n - b ** p, p, b + 1)))
console .log (countPowerSums (100, 2))
I am pretty new to programming, I am getting to know JavaScript, and I've just learned the notion of recursion. Now I am given a problem, to create a function (like const f = function(n) { }) and if we if we call the function with f(5), we should see:
*
***
*****
*******
*********
The number of vertical stars must be determined by the input.
I've got to use no for/while/do-while; recursion only to loop.
I've come up with this code to concatenate 5 stars
const f = function(n) {
if (n === 0) {
return "";
}
return "*" + f(n - 1);
};
console.log(f(5));
Though, I don't see how to make the triangle, what can I do?
You can use this code:
const f = function(chr, n) {
if (n === 0) {
return "";
}
return chr + f(chr, n - 1);
};
const g = function(max) {
const inner = function(n) {
if (n > 1) {
inner(n-1);
}
console.log(f(' ', max-n) + f('*', (n*2)-1));
};
inner(max);
};
g(5);
Please see and play the example below
function pyramid(n, row = 0, level = '') {
if (row === n) {
return
}
if (level.length === n * 2 - 1) {
console.log(level)
return pyramid(n, row + 1)
}
const midpoint = Math.floor((2 * n - 1) / 2)
let add;
if (midpoint - row <= level.length && midpoint + row >= level.length) {
add = '#'
} else {
add = ' '
}
pyramid(n, row, level + add)
}
pyramid(3)
You are on the right way with the
if (n === 0) ...
and the
f(n-1)
these are correct already.
Now you just need to output the correct number of stars in every function call. Look at string.repeat() for that.
If you want to see a complete solution and not just a hint: here is my solution.
function recursiveStar(n){
if(n === 0) return 0;
recursiveStar(n - 1);
return console.log('*'.repeat(n));
}
recursiveStar(5)
You can try this
function pyramid(n, row = 0) {
if (n === row) return;
let midpoint = Math.ceil((n + n - 1) / 2);
let str = "";
for (let j = 1; j <= n + n - 1; j++) {
if (j <= midpoint + row && j >= midpoint - row) str += "#";
else str += " ";
}
console.log(str);
pyramid(n, row + 1);
}
pyramid(5);
As this old question has recently been brought back up, here's an alternative version that treats the depth as constant and recurs on the row number:
const pyramid = (n, r = 0) =>
r > n - 1
? ''
: ' '.repeat ((n - 1 - r)) + '*'.repeat ((2 * r + 1)) + '\n' + pyramid (n, r + 1)
console .log (pyramid (5))
We keep n fixed, starting r at zero, and then recursively incrementing r until it's greater than n. In our base case, when n is 0 and r is 0, we get r > n - 1, and return an empty string. The recursive case proceeds by adding the right number of spaces, the the right number of starts to our first row, and calculating the remaining rows by incrementing r, and recurring.
const pyramid = (n, r = 0) =>
r > n - 1
? ''
: ' ' .repeat ((n - 1 - r)) + '*' .repeat ( (2 * r + 1)) + '\n' + pyramid (n, r + 1)
// `-----------------------' `------------------------' `--' `----------------'
// | | | |
// | | | +-- next rows
// | | +---------------- line break
// | +----------------------------------- asterisks
// +--------------------------------------------------------------- empty spaces
The only slight trickiness in that is the calculation of the correct number of stars and spaces. It's pretty easy to see that for pyramid (5), the spaces should decrease steadily from 4 down to 0 and the asterisks should increase from 1 up to 9. These are captured by the formulas n - 1 - r and 2 * r + 1 respectively.
This was originally for an assignment, and if that assignment didn't allow us to use String.prototype.repeat, then we could easily write our own recursive version in a function like this:
const repeat = (c, n) =>
n < 1 ? '' : c + repeat (c, n - 1)
const pyramid = (n, r = 0) =>
r > n - 1
? ''
: repeat (' ', (n - 1 - r)) + repeat ('*', (2 * r + 1)) + '\n' + pyramid (n, r + 1)
var sum = 0
for (i = 0; i < 250; i++) {
function checkIfPrime() {
for (factor = 2; factor < i; factor++) {
if (i % factor = 0) {
sum = sum;
}
else {
sum += factor;
}
}
}
}
document.write(sum);
I am trying to check for the sum of all the prime numbers under 250. I am getting an error saying that i is invalid in the statement if (i % factor = 0) I know was creating in the original for statement, but is there any way to reference it in the if statement?
With the prime computation, have you considered using Sieve of Eratosthenes? This is a much more elegant way of determining primes, and, summing the result is simple.
var sieve = new Array();
var maxcount = 250;
var maxsieve = 10000;
// Build the Sieve, marking all numbers as possible prime.
for (var i = 2; i < maxsieve; i++)
sieve[i] = 1;
// Use the Sieve to find primes and count them as they are found.
var primes = [ ];
var sum = 0;
for (var prime = 2; prime < maxsieve && primes.length < maxcount; prime++)
{
if (!sieve[prime]) continue;
primes.push(prime); // found a prime, save it
sum += prime;
for (var i = prime * 2; i < maxsieve; i += prime)
sieve[i] = 0; // mark all multiples as non prime
}
document.getElementById("result").value =
"primes: " + primes.join(" ") + "\n"
+ "count: " + primes.length + "\n"
+ "sum: " + sum + "\n";
#result {
width:100%;
height:180px
}
<textarea id="result">
</textarea>
(EDIT) With the updated algorithm, there are now two max involved:
maxcount is the maximum number of prime numbers you wish to find
maxsieve is a guess of sieve large enough to contain maxcount primes
You will have to validate this by actually checking the real count since there are two terminating conditions (1) we hit the limit of our sieve and cannot find any more primes, or (2) we actually found what we're looking for.
If you were to increase the number to numbers much greater than 250, than the Sieve no longer becomes viable as it would be consume great deals of memory. Anyhow, I think this all makes sense right? You really need to play with the Sieve yourself at this point than rely on my interpretation of it.
You can equally use this
let sum = 0;
let num = 250;
for (let i = 2; i < num; i++) {
let isPrime = true;
for (let j = 2; j < i; j++) {
if (i % j === 0) {
isPrime = false;
}
}
if (isPrime) {
sum += i;
}
}
console.log(sum);
i % factor === 0
Use === for comparison. = is for assignment. Yeah I said triple equals. Type coercion is annoying.
You need a == or ===: if (i % factor == 0)
Here's a pretty decent way to do it. It's not as advanced as the sieve but it's a decent starting point. NOTE: I'm using ES6 syntax.
/*
* Sum the first n prime numbers
*
* #param n (integer)
* #return integer
*
*/
function sumNprimes(n){
const arr = [];
let i = 2
while (arr.length < n) {
if (isPrime(i)) {
arr.push(i)
}
i++
}
return arr.reduce( (x,y) => x+y );
/*
* #param n (integer)
* #return Boolean
*
*/
function isPrime(n) {
if ( n < 2 ) {
return false
}
for ( let i = 2; i <= Math.sqrt(n); i++ ) {
if ( n % i === 0 ) {
return false;
}
}
return true
}
}
So i had to face a similar challenge and here is my solution, i hope you find it helpful:
function sumPrimes(num) {
// determine if a number is prime
function isPrime(n) {
if (n === 2) return true;
if (n === 3) return true;
if (n % 2 === 0) return false;
if (n % 3 === 0) return false;
var i = 5;
var w = 2;
while (i * i <= n) {
if (n % i === 0) {
return false;
}
i += w;
w = 6 - w;
}
return true;
}
// subtract 1 for 'not being prime' in my context
var sum = isPrime(num) ? num - 1 : -1;
for (var x = 0; x < num; x++) {
if (isPrime(x) === true) {
sum += x;
}
}
return sum;
}
As per the "Sieve of Eratosthenes", I have implemented the code using JS:
function isPrime(n){
return ((n/2 === 1 || n/3 === 1 || n/5 === 1 || n/7 === 1)?true:(n%2===0 || n%3 === 0 || n%5 ===0 || n%7 === 0)?false:true);
};
var val = 250;
let outArr = [];
for(let i=2;i<val;i++){
if(isPrime(i)){
outArr.push(i);
}
}
console.log("Prime number between 0 - "+val+" : "+outArr.join(","));
Here is a simple way of looping through array and implementing the sieve of Eratosthenes...
function sumPrimes(num) {
var t, v = [],
w = [],
x = [],
y = [],
z = 0;
//enumerating Vee array starts at 2 as first prime number
for (let a = 2; a <= num; a++) {
v.push(a)
}
//creating a moving loop by splicing its first index
for (let i = 0; i < v.length; i) { //ensure all items spliced
t = v[i]; // t as prime to be removed from Vee array
x.push(t); // x storage of primes
z += t // total of peculiar primes
w.push(v.splice(i, 1)) //tested to move all one by one
// prompt(v) //tested that v loses its v[i] every iteration
//= now trying to remove others using remainder (%) vs prime t
for (let vi in v) {
v[vi] % t === 0 ? y.push(v.splice(vi, 1)) : ""; //recursive removal of composite items by prime t
}
}
return z // returns sum of primes
}
sumPrimes(250);
You generate the array beginning with 2 as first prime,
You sieve the array removing items by the remainder of prime using % === 0.
The you loop through the remaining array by using the next prime until the last remaining prime is pushed to the prime arrays. Add all primes to get the Sum.
If the question is purely academical, earlier answers are better suited.
The example below uses modern libraries, in case you need an efficient and elegant solution.
import {generatePrimes} from 'prime-lib';
import {from, reduce, takeWhile} from 'rxjs';
from(generatePrimes())
.pipe(takeWhile(p => p < 250), reduce((a, c) => a + c))
.subscribe(sum => {
// sum = 5830
});
Performance-wise, it will take significantly less than 1ms.
How would it affect the code if I wanted say the sum of the first 250 prime numbers instead of the prime numbers under 250?
You would just replace takeWhile(p => p < 250) with take(250):
import {generatePrimes} from 'prime-lib';
import {from, reduce, take} from 'rxjs';
from(generatePrimes())
.pipe(take(250), reduce((a, c) => a + c))
.subscribe(sum => {
// sum = 182109
});
P.S. I am the author of prime-lib.