Created
January 31, 2020 21:55
-
-
Save iconifyit/aca848be50baa599e5a0c75c5d73ce5c to your computer and use it in GitHub Desktop.
Solution to "Is it a valid number coding test". See the first comment below for test cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The main function. | |
* @param s | |
* @returns {boolean} | |
*/ | |
function isNumber(s) { | |
s = s.trim(); | |
var chars = new Set(s); | |
// Set a sequence point so we knoww | |
var kSEQ = ';'; | |
if (chars.has(kSEQ)) return false; | |
s += kSEQ; | |
var tokens = new Set('0123456789+-.e'), | |
len = s.length, | |
c = '', | |
e = 'e', | |
p = '+', | |
m = '-', | |
d = '.', | |
i = 0, | |
hasE = false, | |
hasS = false, | |
hasD = false, | |
hasN = false; | |
c = s.charAt(i); | |
while (c !== kSEQ) { | |
// This is not a valid token | |
if (! tokens.has(c)) return false; | |
// Is this a sign? | |
else if (c === p || c === m) { | |
// 1 ) If we have seen the sign before, the number is invalid. | |
// 2 ) If we just saw a number, it is invalid. | |
// 3 ) If we have seen `.` but not `e`, it is invalid. | |
if (hasS) return false; | |
if (hasN) return false; | |
if (hasD && ! hasE) return false; | |
// 1 ) Mark the sign. | |
hasS = true; | |
} | |
// Is this a decimal? | |
else if (c === d) { | |
// 1 ) If we have seen the decimal already, the num is invalid. | |
if (hasD) return false; | |
// 1 ) Mark the `.` | |
hasD = true; | |
} | |
// Is this an `e`? | |
else if (c === e) { | |
// 1 ) If we have seen `e` before, the num is invalid. | |
// 2 ) If we have not seen a number, it is invalid. | |
if (hasE) return false; | |
if (! hasN) return false; | |
// 1 ) We can reset the sign value after `e` | |
// 2 ) Mark the `.` as seen (skips useless comparisons) | |
// 3 ) Reset the number marker. | |
// 4 ) Mark the `e` | |
hasS = false; | |
hasD = true; | |
hasN = false; | |
hasE = true; | |
} | |
// Otherwise, it must be a number, just keep reading. | |
else { | |
hasN = true; | |
} | |
c = s.charAt(++i); | |
} | |
return hasN; | |
} |
Author
iconifyit
commented
Jan 31, 2020
•
To use the test data, create a loop to call isNumber(test)
on each item in the tests
array and compare the result to the same item in the expects
array.
tests.map(function(test, i) {
console.log(isNumber(test), expects(i));
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment