Repository: pbiswas101/Mathball (js)

Issue:
Kaprekar Number
### Do the checklist before filing the issue:

- [ ] Is this something you can **debug and fix**?
- [x] Do you have Node.js and all the relevant dev-dependencies installed?
- [ ] Is this a **feature request** that you can add?

###### NOTE: Provide a clear and concise description of the feature that needs to be added! Or if its a bug, then provide the necessary steps to reproduce it.

- *Give your answer below:*

------------

[Function: **M.isKaprekar()**] needs to be added!
For more info:

https://www.geeksforgeeks.org/kaprekar-number/

*M.isKaprekar()* needs to accept a positive integer and all other arguments passed should throw a type error which needs to be handled gracefully! For error handling, you should refer to how other features like M.isArmstrong() is implemented.

Pull request description:
Added popcount()
### Do the checklist before submitting the PR:

- [:heavy_check_mark: ] Have you read the guidelines mentioned in **CONTRIBUTING.md**?
   Yes
- [ ] Have you squashed your commits?

**Q**: What version of *Node.js* you've used in the project? (`e.g. Node v10.11.0`)
**A**:v11.6.0

**Q**: Mention the *Issue Number*! (`e.g. Fixed #8`)
**A**:Fixed Issue #129.

- *Give additional information regarding the PR below:*
popcount() takes an non-negative integer and counts the no. of 1s bits in the integer.
------------


Patch:
diff --git a/README.md b/README.md
index 9a8047e..f825df1 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ $ npm install mathball --save
 
 - **Range of Numbers** - [rangePrime][7] - [range][66] - [rangePalindrome][6]
 
-- **Mathematical Utilities** - [Complex][49] - [frequency][40] - [gcd][10] - [getAllPerm][55] - [isEven][11] - [isOdd][12] - [lcm][13] - [length][14] - [max][15] - [median][64] - [min][16] - [modInv][39] - [nCr][48] - [pow][46] - [sort][17] - [sum][18] - [toDegrees][50] - [toRadians][51] - [matrixMultiply][58] - [matrixExpo][59] - [matrixChain][60] - [count][61] - [avg][62] - [findPrimeFactors][63] - [phi][67] - [addition][112] - [subtraction][113] - [multiplication][114] - [division][115] - [absolute][116]
+- **Mathematical Utilities** - [Complex][49] - [frequency][40] - [gcd][10] - [getAllPerm][55] - [isEven][11] - [isOdd][12] - [lcm][13] - [length][14] - [max][15] - [median][64] - [min][16] - [modInv][39] - [nCr][48] - [pow][46] - [sort][17] - [sum][18] - [toDegrees][50] - [toRadians][51] - [matrixMultiply][58] - [matrixExpo][59] - [matrixChain][60] - [count][61] - [avg][62] - [findPrimeFactors][63] - [phi][67] - [addition][112] - [subtraction][113] - [multiplication][114] - [division][115] - [absolute][116] - [popcount][117]
 
 - **Data Structures** - [priorityQueue][44] - [stack][53] - [graph][57]
 
@@ -138,3 +138,4 @@ The MIT License 2019 - [Priyabrata Biswas][20].
 [114]: https://github.com/pbiswas101/Mathball/blob/master/src/multiplication/index.js
 [115]: https://github.com/pbiswas101/Mathball/blob/master/src/division/index.js
 [116]: https://github.com/pbiswas101/Mathball/blob/master/src/absolute/index.js
+[117]: https://github.com/pbiswas101/Mathball/blob/master/src/popcount/index.js
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 7b96e5f..0bc845b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5198,4 +5198,4 @@
       "dev": true
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 5b8c11a..6093cc2 100644
--- a/src/index.js
+++ b/src/index.js
@@ -50,6 +50,7 @@ const avg = require('./avg'),
 	matrixMultiply = require('./matrixMultiply'),
 	matrixChain = require('./matrixChain'),
 	matrixExpo = require('./matrixExponentiation'),
+	popcount = require('./popcount'),
 	pow = require('./pow'),
 	sort = require('./sort'),
 	sum = require('./sum'),
@@ -108,6 +109,7 @@ module.exports = {
 	isFrugal: isFrugal.isFrugal,
 	performance,
 	pipe,
+	popcount,
 	pow,
 	phi: totient.phi,
 	isStormer: isStormer.isStormer,
diff --git a/src/popcount/index.js b/src/popcount/index.js
new file mode 100644
index 0000000..fdb9a52
--- /dev/null
+++ b/src/popcount/index.js
@@ -0,0 +1,17 @@
+/* Function: popcount() */
+
+const validate = require('../validation/positive-integer');
+
+function popcount(num) {
+	let count = 0;
+    while (num){ 
+        num &= (num-1);  
+        count++;
+    }
+    return count;
+ }
+
+module.exports = num => {
+	validate(num, 'popcount');
+	return popcount(num);
+};


Test patch:
diff --git a/test/popcount-spec.js b/test/popcount-spec.js
new file mode 100644
index 0000000..1ef2185
--- /dev/null
+++ b/test/popcount-spec.js
@@ -0,0 +1,38 @@
+const assert = require('assert'),
+	popcount = require('../src/popcount');
+
+describe('[Function: popcount]', () => {
+
+	it('should be a function', () => {
+		assert.strictEqual(typeof popcount, 'function');
+	});
+
+	it('should return a number when a positive integer is passed', () => {
+		assert.strictEqual(typeof popcount(1), 'number');
+	});
+
+	it('should return \'2\' when \'6\' is passed', () => {
+		assert.strictEqual(popcount(6), 2);
+	});
+
+	it('should return \'4\' when \'15\' is passed', () => {
+		assert.strictEqual(popcount(15), 4);
+	});
+
+	it('should throw an error when a negative number is passed', () => {
+		assert.throws(() => popcount(-20), TypeError);
+	});
+
+	it('should throw an error when a floating point is passed', () => {
+		assert.throws(() => popcount(27.996), TypeError);
+	});
+
+	it('should throw an error when a string is passed', () => {
+		assert.throws(() => popcount('47'), TypeError);
+	});
+
+	it('should throw an error when no arguments passed', () => {
+		assert.throws(() => popcount(), TypeError);
+	});
+
+});
\ No newline at end of file