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:
Carmichael Number #1
*Added Carmichael Number function

*Added Carmichael Number in index and readme

*Added Unit Tests in carmichael-spec

### Do the checklist before submitting the PR:

- [:heavy_check_mark:] Have you read the guidelines mentioned in **CONTRIBUTING.md**?
- [:heavy_check_mark:] 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.10.1

**Q**: Mention the *Issue Number*! (`e.g. Fixed #8`)
**A**:#1

- *Give additional information regarding the PR below:*

------------


Patch:
diff --git a/README.md b/README.md
index db2dd3c..06702da 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ $ npm install mathball --save
 
 ## Features
 
-- **Number Checkers** - [isArmstrong][3] - [isAutomorphic][4] - [isKaprekar][23] - [isLucky][24] - [isNeon][5] - [isPalindrome][6] - [isPerfect][27] - [isPrime][7] - [isSmith][26] - [isDeficient][42]
+- **Number Checkers** - [isArmstrong][3] - [isAutomorphic][4] - [isKaprekar][23] - [isLucky][24] - [isNeon][5] - [isPalindrome][6] - [isPerfect][27] - [isPrime][7] - [isSmith][26] - [isDeficient][42] - [isCarmichael][43]
 
 - **Find nth Number** - [bell][32] - [catalan][22] - [factorial][21] - [fibonacci][8] - [magic][9] - [smart][25] - [padovan][41]
 
@@ -104,3 +104,4 @@ The MIT License 2019 - [Priyabrata Biswas][20].
 [40]: https://github.com/pbiswas101/Mathball/blob/master/src/frequency/index.js
 [41]: https://github.com/pbiswas101/Mathball/blob/master/src/padovan/index.js
 [42]: https://github.com/pbiswas101/Mathball/blob/master/src/isDeficient/index.js
+[43]: https://github.com/pbiswas101/Mathball/blob/master/src/carmichael/index.js
diff --git a/src/carmichael/index.js b/src/carmichael/index.js
new file mode 100644
index 0000000..130ee8e
--- /dev/null
+++ b/src/carmichael/index.js
@@ -0,0 +1,32 @@
+/* Carmichael Number
+* Function: isCarmichael()
+*/
+
+const validate = require('../validation/positive-integer');
+const prime = require('../prime');
+
+function squarefree(i){
+	for(let k = 2; (k <= Math.sqrt(i) && i % k !== 0 && i/k % k !== 0); k++){
+		return true;
+	}
+}
+
+function isCarmichael(n){
+	let c = 0;
+	for(let i = 1; i <= n; i++){
+		if(n % i == 0){
+			if(prime.isPrime(i) && ((n-1) % (i-1) == 0)){
+				c++;
+				if(c >= 3 && i % 2 != 0 && squarefree(i)){
+					return true;
+
+				}
+			}
+		}
+	}
+	return false;
+}
+exports.isCarmichael = n => {
+	validate(n, 'isCarmichael');
+	return isCarmichael(n);
+};
diff --git a/src/index.js b/src/index.js
index ffb2284..c1dc1d6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -8,7 +8,8 @@ const armstrong = require('./armstrong'),
 	perfect = require('./perfect'),
 	prime = require('./prime'),
 	smith = require('./smith'),
-	isDeficient = require('./isDeficient');
+	isDeficient = require('./isDeficient'),
+	carmichael = require('./carmichael');
 
 /* Find nth Number */
 const bell = require('./bell'),
@@ -68,5 +69,6 @@ module.exports = {
 	sum,
 	modInv: modInv.modInv,
 	frequency,
-	isDeficient
+	isDeficient,
+	isCarmichael: carmichael.isCarmichael
 };


Test patch:
diff --git a/test/carmichael-spec.js b/test/carmichael-spec.js
new file mode 100644
index 0000000..6f23592
--- /dev/null
+++ b/test/carmichael-spec.js
@@ -0,0 +1,36 @@
+const assert = require("assert"),
+	isCarmichael = require("../src/carmichael").isCarmichael;
+
+describe("[Function: isCarmichael]", () => {
+	it('should be a function', () => {
+		assert.strictEqual(typeof isCarmichael, 'function');
+	});
+
+	it('should return a boolean value when a positive integer is passed', () => {
+		assert.strictEqual(typeof isCarmichael(8), 'boolean');
+	});
+
+	it('should return true when 561 is passed', () => {
+		assert.strictEqual(isCarmichael(561), true);
+	});
+
+	it('should return false if 8 is passed', () => {
+		assert.strictEqual(isCarmichael(8), false);
+	});
+
+	it('should throw an error when a negative number is passed', () => {
+		assert.throws(() => isCarmichael(-10), TypeError);
+	});
+
+	it('should throw an error when a floating point is passed', () => {
+		assert.throws(() => isCarmichael(7.2), TypeError);
+	});
+
+	it('should throw an error when a string is passed', () => {
+		assert.throws(() => isCarmichael('hello'), TypeError);
+	});
+
+	it('should throw an error when no arguments are passed', () => {
+		assert.throws(() => isCarmichael(), TypeError);
+	});
+});