UNPKG

isxxxx

Version:

Lightweight library for checking number properties and mathematical classifications

569 lines (449 loc) 13.9 kB
function isEven(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num % 2 === 0; } function isOdd(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num % 2 !== 0; } function isPositive(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num > 0; } function isNegative(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num < 0; } function isZero(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num === 0; } function isPrime(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 1) return false; if (num <= 3) return true; if (num % 2 === 0 || num % 3 === 0) return false; let i = 5; while (i * i <= num) { if (num % i === 0 || num % (i + 2) === 0) return false; i += 6; } return true; } function isMultipleOf(num, multiple) { if (typeof num !== 'number' || typeof multiple !== 'number') throw new TypeError('Expected numbers'); if (multiple === 0) throw new Error('Cannot check for multiples of zero'); return num % multiple === 0; } function isInRange(num, min, max) { if (typeof num !== 'number' || typeof min !== 'number' || typeof max !== 'number') throw new TypeError('Expected numbers'); return num >= min && num <= max; } function isPerfectSquare(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const sqrt = Math.sqrt(num); return Math.floor(sqrt) === sqrt; } function isInteger(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return Number.isInteger(num); } function isPowerOfTwo(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return num > 0 && (num & (num - 1)) === 0; } function isPowerOf(num, base) { if (typeof num !== 'number' || typeof base !== 'number') throw new TypeError('Expected numbers'); if (base <= 0 || num <= 0) return false; if (base === 1) return num === 1; let power = 1; while (power < num) { power *= base; } return power === num; } function isPerfect(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 1) return false; let sum = 1; for (let i = 2; i * i <= num; i++) { if (num % i === 0) { sum += i; if (i !== num / i) sum += num / i; } } return sum === num; } function isFibonacci(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; return isPerfectSquare(5 * num * num + 4) || isPerfectSquare(5 * num * num - 4); } function isFactorial(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 1) return false; if (num === 1) return true; let factorial = 1, i = 2; while (factorial < num) { factorial *= i++; } return factorial === num; } function isPalindrome(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const str = num.toString(); const len = str.length; for (let i = 0; i < len / 2; i++) { if (str[i] !== str[len - 1 - i]) return false; } return true; } function isSafeInteger(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); return Number.isSafeInteger(num); } function isTriangular(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const check = 8 * num + 1; const sqrt = Math.sqrt(check); return Math.floor(sqrt) === sqrt; } function isHexagonal(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const check = 8 * num + 1; const sqrt = Math.sqrt(check); return Math.floor(sqrt) === sqrt && sqrt % 2 === 1; } function isPentagonal(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const check = 24 * num + 1; const sqrt = Math.sqrt(check); return sqrt === Math.floor(sqrt) && (sqrt + 1) % 6 === 0; } function isArmstrong(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const digits = num.toString().split('').map(Number); const power = digits.length; const sum = digits.reduce((acc, digit) => acc + Math.pow(digit, power), 0); return sum === num; } function isHappy(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; const seen = new Set(); while (num !== 1 && !seen.has(num)) { seen.add(num); num = num.toString().split('').reduce((sum, digit) => sum + Math.pow(Number(digit), 2), 0); } return num === 1; } function isHarshad(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; const digitSum = num.toString().split('').reduce((sum, digit) => sum + Number(digit), 0); return num % digitSum === 0; } function isSmith(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 1) return false; if (isPrime(num)) return false; const digitSum = num.toString().split('').reduce((sum, digit) => sum + Number(digit), 0); let n = num; let primeFactorSum = 0; for (let i = 2; i * i <= n; i++) { while (n % i === 0) { primeFactorSum += i.toString().split('').reduce((sum, digit) => sum + Number(digit), 0); n /= i; } } if (n > 1) { primeFactorSum += n.toString().split('').reduce((sum, digit) => sum + Number(digit), 0); } return digitSum === primeFactorSum; } function isPowerful(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; if (num === 1) return true; let n = num; for (let i = 2; i * i <= n; i++) { if (n % i === 0) { if (n % (i * i) !== 0) return false; while (n % i === 0) n /= i; } } return n > 1 ? num % (n * n) === 0 : true; } function isAbundant(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; let sum = 0; for (let i = 1; i <= num / 2; i++) { if (num % i === 0) sum += i; } return sum > num; } function isDeficient(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; let sum = 0; for (let i = 1; i <= num / 2; i++) { if (num % i === 0) sum += i; } return sum < num; } function isSelfNumber(num, limit = 10000) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; if (limit > 100000) limit = 100000; const upperBound = Math.min(num, limit); for (let i = 1; i <= upperBound; i++) { const digitSum = i.toString().split('').reduce((sum, digit) => sum + Number(digit), 0); if (i + digitSum === num) return false; } return true; } function isAutomorphic(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; return (num * num).toString().endsWith(num.toString()); } function isNarcissistic(num) { return isArmstrong(num); } function isCarmichael(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 1) return false; if (isPrime(num)) return false; function modPow(base, exponent, modulus) { if (modulus === 1) return 0; let result = 1; base = base % modulus; while (exponent > 0) { if (exponent % 2 === 1) result = (result * base) % modulus; exponent = Math.floor(exponent / 2); base = (base * base) % modulus; } return result; } function gcd(a, b) { while (b !== 0) { const temp = b; b = a % b; a = temp; } return a; } for (let a = 2; a < num; a++) { if (gcd(a, num) === 1 && modPow(a, num - 1, num) !== 1) return false; } return true; } function isKaprekar(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 1) return false; const square = num * num; const squareStr = square.toString(); for (let i = 1; i < squareStr.length; i++) { const part1 = parseInt(squareStr.substring(0, i), 10); const part2 = parseInt(squareStr.substring(i), 10); if (part2 > 0 && part1 + part2 === num) return true; } return false; } function isAlternating(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const digits = num.toString().split('').map(Number); if (digits.length <= 1) return true; for (let i = 1; i < digits.length; i++) { if ((digits[i] % 2 === 0) === (digits[i-1] % 2 === 0)) return false; } return true; } function isApocalyptic(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; return (BigInt(2) ** BigInt(num)).toString().includes('666'); } function isLucas(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num === 2 || num === 1) return true; if (num < 0) return false; let a = 2, b = 1, c; while (b < num) { c = a + b; a = b; b = c; if (b === num) return true; } return false; } function isCatalan(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; const smallCatalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440]; if (num <= 2674440) return smallCatalans.includes(num); let catalan = 1, n = 1; while (catalan < num) { catalan = (catalan * (4 * n - 2)) / (n + 1); n++; if (catalan === num) return true; } return false; } function isBell(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; const smallBells = [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597]; return smallBells.includes(num); } function isMersennePrime(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; return !((num + 1) & num) && isPrime(num); } function isFermat(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; if ([3, 5, 17, 257, 65537].includes(num)) return true; if (num < 65537) return false; for (let n = 5; n <= 20; n++) { try { const fermat = BigInt(2) ** BigInt(2 ** n) + BigInt(1); if (fermat.toString() === num.toString()) return true; if (fermat > BigInt(Number.MAX_SAFE_INTEGER)) break; } catch (e) { break; } } return false; } function isCullen(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; for (let n = 1; n <= 100; n++) { const cullen = n * Math.pow(2, n) + 1; if (cullen === num) return true; if (cullen > num) return false; } return false; } function isWoodall(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; for (let n = 1; n <= 100; n++) { const woodall = n * Math.pow(2, n) - 1; if (woodall === num) return true; if (woodall > num) return false; } return false; } function isPronic(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const sqrt = Math.sqrt(num); const floor = Math.floor(sqrt); return floor * (floor + 1) === num; } function isRepunit(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; return /^1+$/.test(num.toString()); } function isSquareFree(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; for (let i = 2; i * i <= num; i++) { if (num % (i * i) === 0) return false; } return true; } function isUndulant(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num < 0) return false; const digits = num.toString().split('').map(Number); if (digits.length <= 2) return false; for (let i = 1; i < digits.length - 1; i++) { if (!((digits[i-1] < digits[i] && digits[i] > digits[i+1]) || (digits[i-1] > digits[i] && digits[i] < digits[i+1]))) { return false; } } return true; } function isPractical(num) { if (typeof num !== 'number') throw new TypeError('Expected a number'); if (num <= 0) return false; if (num === 1) return true; const divisors = [1]; for (let i = 2; i <= Math.sqrt(num); i++) { if (num % i === 0) { divisors.push(i); if (i !== num / i) divisors.push(num / i); } } divisors.sort((a, b) => a - b); for (let i = 1; i < Math.pow(2, divisors.length); i++) { let sum = 0; for (let j = 0; j < divisors.length; j++) { if ((i >> j) & 1) sum += divisors[j]; } if (sum >= 1 && sum < num && !divisors.includes(sum)) return false; } return true; } module.exports = { isEven, isOdd, isPositive, isNegative, isZero, isPrime, isMultipleOf, isInRange, isPerfectSquare, isInteger, isPowerOfTwo, isPowerOf, isPerfect, isFibonacci, isFactorial, isPalindrome, isSafeInteger, isTriangular, isHexagonal, isPentagonal, isArmstrong, isHappy, isHarshad, isSmith, isPowerful, isAbundant, isDeficient, isSelfNumber, isAutomorphic, isNarcissistic, isCarmichael, isKaprekar, isAlternating, isApocalyptic, isLucas, isCatalan, isBell, isMersennePrime, isFermat, isCullen, isWoodall, isPronic, isRepunit, isSquareFree, isUndulant, isPractical };