Repository: pbiswas101/Mathball (js)

Issue:
Smith 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.isSmith()**] needs to be added!
For more info:

https://www.geeksforgeeks.org/smith-number/

*M.isSmith()* 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:
Added isSmith() Function
Node v10.12.0
Fixes #14 

------------


Patch:
diff --git a/README.md b/README.md
index 874ad11..3e32915 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
 # Introduction
 
-[![npm version](https://badge.fury.io/js/mathball.svg)](https://badge.fury.io/js/mathball) [![Build Status](https://travis-ci.org/pbiswas101/Mathball.svg?branch=master)](https://travis-ci.org/pbiswas101/Mathball) [![Known Vulnerabilities](https://snyk.io/test/github/pbiswas101/Mathball/badge.svg?targetFile=package.json)](https://snyk.io/test/github/pbiswas101/Mathball?targetFile=package.json) [![codecov](https://codecov.io/gh/pbiswas101/Mathball/branch/master/graph/badge.svg)](https://codecov.io/gh/pbiswas101/Mathball) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1750f9ec92a14adea5593be4ad56d3a2)](https://www.codacy.com/app/pbiswas101/Mathball?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=pbiswas101/Mathball&amp;utm_campaign=Badge_Grade) ![](https://img.shields.io/github/issues/pbiswas101/Mathball.svg) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) ![](https://img.shields.io/github/stars/pbiswas101/Mathball.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
+[![npm version](https://badge.fury.io/js/mathball.svg)](https://badge.fury.io/js/mathball) [![Build Status](https://travis-ci.org/pbiswas101/Mathball.svg?branch=master)](https://travis-ci.org/pbiswas101/Mathball) [![Known Vulnerabilities](https://snyk.io/test/github/pbiswas101/Mathball/badge.svg?targetFile=package.json)](https://snyk.io/test/github/pbiswas101/Mathball?targetFile=package.json) [![codecov](https://codecov.io/gh/pbiswas101/Mathball/branch/master/graph/badge.svg)](https://codecov.io/gh/pbiswas101/Mathball) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1750f9ec92a14adea5593be4ad56d3a2)](https://www.codacy.com/app/pbiswas101/Mathball?utm_source=github.com&utm_medium=referral&utm_content=pbiswas101/Mathball&utm_campaign=Badge_Grade) ![](https://img.shields.io/github/issues/pbiswas101/Mathball.svg) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) ![](https://img.shields.io/github/stars/pbiswas101/Mathball.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
 
 ![](https://github.com/pbiswas101/Mathball/blob/master/assets/mathball-banner.png)
 
 **Mathball** is an npm package for competitive programming in [JavaScript][1] with a focus on common mathematical utilities being implemented in relevant algorithms & data structures for optimized performance!
 
-JavaScript was never built while keeping competitive coding in mind; let us all agree on that. But, the stuff that we build with it today was not something it was built for either! Back in 1995, [Brendan Eich][2] designed JS only for adding interactivity to web pages; and now with it, we can build *web servers*, *microservices*, *games*, *mobile apps*, *IoT apps*, *ML in the browser*, and so on. Based on the notion - **JS is everywhere!** I also believe that maybe its time to motivate people who are well versed with this language to finally consider it in the realm of competitive programming.
+JavaScript was never built while keeping competitive coding in mind; let us all agree on that. But, the stuff that we build with it today was not something it was built for either! Back in 1995, [Brendan Eich][2] designed JS only for adding interactivity to web pages; and now with it, we can build _web servers_, _microservices_, _games_, _mobile apps_, _IoT apps_, _ML in the browser_, and so on. Based on the notion - **JS is everywhere!** I also believe that maybe its time to motivate people who are well versed with this language to finally consider it in the realm of competitive programming.
 
 ## Installation
 
@@ -18,32 +18,11 @@ $ npm install mathball --save
 
 ## Features
 
-- **Number Checkers**
-	- [isArmstrong()][3]
-	- [isAutomorphic()][4]
-	- [isKaprekar()][23]
-	- [isLucky()][24]
-	- [isNeon()][5]
-	- [isPalindrome()][6]
-	- [isPrime()][7]
-
-- **Find nth Number**
-	- [catalan()][22]
-	- [factorial()][21]
-	- [fibonacci()][8]
-	- [magic()][9]
-	- [smart()][25]
-
-- **Mathematical Utilities**
-	- [gcd()][10]
-	- [isEven()][11]
-	- [isOdd()][12]
-	- [lcm()][13]
-	- [length()][14]
-	- [max()][15]
-	- [min()][16]
-	- [sort()][17]
-	- [sum()][18]
+- **Number Checkers** - [isArmstrong()][3] - [isAutomorphic()][4] - [isKaprekar()][23] - [isLucky()][24] - [isNeon()][5] - [isPalindrome()][6] - [isPrime()][7] - [isSmith()][26]
+
+- **Find nth Number** - [catalan()][22] - [factorial()][21] - [fibonacci()][8] - [magic()][9] - [smart()][25]
+
+- **Mathematical Utilities** - [gcd()][10] - [isEven()][11] - [isOdd()][12] - [lcm()][13] - [length()][14] - [max()][15] - [min()][16] - [sort()][17] - [sum()][18]
 
 ## Examples
 
@@ -102,3 +81,4 @@ The MIT License 2018 - [Priyabrata Biswas][20].
 [23]: https://github.com/pbiswas101/Mathball/blob/master/src/kaprekar/index.js
 [24]: https://github.com/pbiswas101/Mathball/blob/master/src/lucky/index.js
 [25]: https://github.com/pbiswas101/Mathball/blob/master/src/smart/index.js
+[26]: https://github.com/pbiswas101/Mathball/blob/master/src/smith/index.js
diff --git a/src/index.js b/src/index.js
index af09cc4..f74821f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -11,7 +11,8 @@ const armstrong = require("./armstrong"),
 	catalan = require("./catalan"),
 	kaprekar = require("./kaprekar"),
 	lucky = require("./lucky"),
-	smart = require("./smart");
+	smart = require("./smart"),
+	smith = require("./smith");
 
 /* Mathematical Utilities */
 
@@ -40,6 +41,7 @@ module.exports = {
 	isKaprekar: kaprekar.isKaprekar,
 	isLucky: lucky.isLucky,
 	smart: smart.smart,
+	isSmith: smith.isSmith,
 	gcd,
 	isEven,
 	isOdd,
diff --git a/src/smith/index.js b/src/smith/index.js
new file mode 100644
index 0000000..4363b74
--- /dev/null
+++ b/src/smith/index.js
@@ -0,0 +1,74 @@
+/* Smith Number
+ * Function: isSmith()
+ */
+
+function validate(arg) {
+	if (typeof arg != "number" || arg < 1 || !Number.isInteger(arg)) {
+		throw new TypeError(
+			`Invalid argument recieved: ${JSON.stringify(
+				arg
+			)}\n'isSmith()' only accept a positive integer!\n`
+		);
+	}
+}
+
+var primes = new Array();
+const MAX = 10000;
+
+function sieveSundaram() {
+	var marked = new Array(Math.floor(MAX / 2) + 100);
+	for (let i = 0; i < Math.floor(MAX / 2) + 100; i++) {
+		marked[i] = false;
+	}
+
+	for (let i = 1; i <= Math.floor((Math.sqrt(MAX) - 1) / 2); i++) {
+		for (
+			let j = (i * (i + 1)) << 1;
+			j <= Math.floor(MAX / 2);
+			j = j + 2 * i + 1
+		) {
+			marked[j] = true;
+		}
+	}
+	primes.push(2);
+	for (let i = 1; i <= Math.floor(MAX / 2); i++) {
+		if (marked[i] === false) {
+			primes.push(2 * i + 1);
+		}
+	}
+}
+
+function smith(num) {
+	var originalNo = num;
+	var pDigitSum = 0;
+	for (let i = 0; primes[i] <= Math.floor(num / 2); i++) {
+		while (num % primes[i] === 0) {
+			var p = primes[i];
+			num = Math.floor(num / p);
+			while (p > 0) {
+				pDigitSum = pDigitSum + (p % 10);
+				p = Math.floor(p / 10);
+			}
+		}
+	}
+
+	if (num !== 1 && num !== originalNo) {
+		while (num > 0) {
+			pDigitSum = pDigitSum + (num % 10);
+			num = Math.floor(num / 10);
+		}
+	}
+
+	var sumDigits = 0;
+	while (originalNo > 0) {
+		sumDigits = sumDigits + (originalNo % 10);
+		originalNo = Math.floor(originalNo / 10);
+	}
+	return pDigitSum === sumDigits;
+}
+
+exports.isSmith = num => {
+	validate(num);
+	sieveSundaram();
+	return smith(num);
+};


Test patch:
diff --git a/test/smith-spec.js b/test/smith-spec.js
new file mode 100644
index 0000000..2617092
--- /dev/null
+++ b/test/smith-spec.js
@@ -0,0 +1,36 @@
+const assert = require("assert"),
+	isSmith = require("../src/smith").isSmith;
+
+describe("[Function: isSmith]", () => {
+	it("should be a function", () => {
+		assert.strictEqual(typeof isSmith, "function");
+	});
+
+	it("should return a boolean value when a positive integer is passed", () => {
+		assert.strictEqual(typeof isSmith(1), "boolean");
+	});
+
+	it("should return 'true' when '483' is passed", () => {
+		assert.strictEqual(isSmith(483), true);
+	});
+
+	it("should return 'false' when '34' is passed", () => {
+		assert.strictEqual(isSmith(34), false);
+	});
+
+	it("should throw an error when a negative number is passed", () => {
+		assert.throws(() => isSmith(-20), TypeError);
+	});
+
+	it("should throw an error when a floating point is passed", () => {
+		assert.throws(() => isSmith(31.101996), TypeError);
+	});
+
+	it("should throw an error when a string is passed", () => {
+		assert.throws(() => isSmith("31"), TypeError);
+	});
+
+	it("should throw an error when no arguments passed", () => {
+		assert.throws(() => isSmith(), TypeError);
+	});
+});