Is finding the factorial of 5000 possible in javascript - javascript

I want to find the factorial of 5000 but once I try to pass 100 it'll return infinity. Is there are way to bypass this and get the result? I am trying to get the time it takes to solve this.
function testSpeed(n) {
if (n > 0 && n <= 1) {
return 1;
} else {
return n * testSpeed(n-1);
}
}
console.log(testSpeed(5000));

As you've noticed, Javascript numbers can only get so big before they just become "Infinity". If you want to support bigger numbers, you'll have to use BigInt.
Examples:
// Without BigInt
console.log(100 ** 1000) // Infinity
// With BigInt
// (stackOverflow doesn't seem to print the result,
// unless I turn it into a string first)
console.log(String(100n ** 1000n)) // A really big number
So, for your specific bit of code, all you need to do is turn your numeric literals into BigInt literals, like this:
function testSpeed(n) {
if (n > 0n && n <= 1n) {
return 1n;
} else {
return n * testSpeed(n-1n);
}
}
console.log(String(testSpeed(5000n)));
You'll find that youe computer can run that piece of code in a snap.

This seems to give the correct result (according to https://coolconversion.com/math/factorial/What-is-the-factorial-of_5000_%3F)
const longFactorial = (num) => {
let result = num;
for (let i = 1n; i < num; i++) {
result = result * (num - i)
}
return String(result);
}
console.log(longFactorial(5000n));

I can receive for 170! maximum:
function factorial (y){
if (y ==0 || y ==1){
return 1;
}
else {
f = y - 1;
while (f >= 1) {
y = y * f;
f--;
}
return y;
}
}
console.log(factorial(170));

Related

Javascript function that finds the next largest palindrome number

I want to write a function that finds the next largest palindrome for a given positive integer. For example:
Input: 2
Output: 3 (every single digit integer is a palindrome)
Input: 180
Output: 181
Input: 17
Output: 22
My try
function nextPalindrome(num) {
let input = num;
let numToStringArray = input.toString().split('');
let reversedArray = numToStringArray.reverse();
if (numToStringArray.length < 2) {
return Number(numToStringArray) + 1;
} else {
while (numToStringArray !== reversedArray) {
// numToStringArray = num.toString().split('');
// reversedArray = numToStringArray.reverse();
num += 1;
}
return numToStringArray.join('');
}
}
As a beginner, I thought that the numToStringArray would constantly increment by 1 and check for whether the while-statement is true.
Unfortunately it doesn't. I commented out two lines in the while-statement because they seemed somewhat redundant to me. Thanks to everyone reading or even helping me out!
The reason your code doesn't work is because you don't have any code updating the conditions of your while loop. So if you enter it once, it will loop indefinitely. You need to do something inside of the while loop that might make the condition false the next time through the loop, like so:
function getReverse(num) {
// get the reverse of the number (in positive number form)
let reversedNum = +Math.abs(num).toString().split("").reverse().join("");
// keep negative numbers negative
if (num < 0) { reversedNum *= -1; }
return reversedNum;
}
function nextPalindrome(num) {
// if single digit, simply return the next highest integer
if (num >= -10 && num < 9) {
return num+1;
}
else {
while(num !== getReverse(num)) {
num += 1;
}
return num;
}
}
console.log(nextPalindrome(3));
console.log(nextPalindrome(17));
console.log(nextPalindrome(72));
console.log(nextPalindrome(180));
console.log(nextPalindrome(1005));
console.log(nextPalindrome(-150));
console.log(nextPalindrome(-10));
You could also solve this pretty cleanly using recursion, like so:
function getReverse(num) {
// get the reverse of the number (in positive number form)
let reversedNum = +Math.abs(num).toString().split("").reverse().join("");
// keep negative numbers negative
if (num < 0) { reversedNum *= -1; }
return reversedNum;
}
function nextPalindrome(num) {
// if single digit, simply return the next highest integer
if (num >= -10 && num < 9) {
return num+1;
}
else if(num === getReverse(num)) {
return num;
}
else {
// if not the same, recurse with n + 1
return nextPalindrome(num + 1)
}
}
console.log(nextPalindrome(3));
console.log(nextPalindrome(17));
console.log(nextPalindrome(72));
console.log(nextPalindrome(180));
console.log(nextPalindrome(1005));
console.log(nextPalindrome(-150));
console.log(nextPalindrome(-10));

Transform this iteration function to recursive

This is a function to display the sum of the input digits with iteration perspective:
function sumOfDigits(number) {
let strNumber = number.toString()
let output = 0;
for(i=0;i<strNumber.length;i++){
let tmp = parseInt(strNumber[i])
output = output + tmp
}
return output
}
// TEST CASES
console.log(sumOfDigits(512)); // 8
console.log(sumOfDigits(1542)); // 12
console.log(sumOfDigits(5)); // 5
console.log(sumOfDigits(21)); // 3
console.log(sumOfDigits(11111)); // 5
I am wondering how we write this function in a recursive way?
Using the modulo operator, you can get the remainder (which in the case of a divison by 10, is the last number) and then add the next iteration.
function sumOfDigits (n) {
if (n === 0) return 0
return (n % 10 + sumOfDigits(Math.floor(n / 10)))
}
console.log(sumOfDigits(512))
If you want to see a more detailed explanation, check https://www.geeksforgeeks.org/sum-digit-number-using-recursion/
I have not tested it, but you can try the following without casting to string
function sumOfDigits(number)
{
if (number === 0) {
return 0;
}
return (number % 10 + sumOfDigits(Math.floor(number / 10)));
}
Make sure that the input is indeed in number format
Here you go
function sumOfDigitsRecursive(number){
let strNumber = number.toString()
if(strNumber.length<=0)
return 0
return parseInt(strNumber[0])+sumOfDigitsRecursive(strNumber.slice(1,strNumber.length))
}

making a factorial in javascript with recursion beginner

function nFactorial(n) {
// return the factorial for n
// example:
// the factorial of 3 is 6 (3 * 2 * 1)
if (n < 0){
return;
}
if (sum === undefined){
sum = 1;
}
sum *= n;
nFactorial(n - 1);
return sum;
}
nFactorial(3);
I'm doing my first stab at learning recursion in javascript. I'm trying to solve a problem where I'm making a factorial. I error I get right now is
ReferenceError: sum is not defined
Can anyone point me in the right direction? I'm feeling a little lost.
For using a product as return value, you could use tail call optimization of the recursion by using another parameter for the product (which replaces the sum in the question).
function nFactorial(n, product) {
product = product || 1; // default value
if (n < 0) { // exit condition without value
return;
}
if (n === 0) { // exit condition with result
return product;
}
return nFactorial(n - 1, n * product); // call recursion at the end of function
}
console.log(nFactorial(3));
This approach minimizes the stack length, because the last call does not extend the stack, as opposite of the standard approach of the following recursion without a product parameter.
function nFactorial(n) {
if (n < 0) {
return;
}
if (n === 0) {
return 1;
}
return n * nFactorial(n - 1);
}
console.log(nFactorial(3));
the way you write your code will result always in 0 , here is the correct way for a factorial with recursion, also you need to check if n is a number or the code will trow an error
const factorial =(n)=> {
if(isNaN(n)){
console.log("enter a number")
return 0
}
if(n === 0) {
return 1
} else {
return n * factorial(n - 1);
}
}
console.log(factorial(5));
A simple implementation:
function factorial(n) {
if (n === 1 || n === 0) {
return n;
}
return n * factorial(n-1);
}

JavaScript - Improving algorithm for finding square roots of perfect squares without Math.sqrt

I'm trying to learn algorithms and coding stuff by scratch. I wrote a function that will find square roots of square numbers only, but I need to know how to improve its performance and possibly return square roots of non square numbers
function squareroot(number) {
var number;
for (var i = number; i >= 1; i--) {
if (i * i === number) {
number = i;
break;
}
}
return number;
}
alert(squareroot(64))
Will return 8
Most importantly I need to know how to improve this performance. I don't really care about its limited functionality yet
Here is a small improvement I can suggest. First - start iterating from 0. Second - exit loop when the square of root candidate exceeds the number.
function squareroot(number) {
for (var i = 0; i * i <= number; i++) {
if (i * i === number)
return i;
}
return number; // don't know if you should have this line in case nothing found
}
This algo will work in O(√number) time comparing to initial O(n) which is indeed performance improvement that you asked.
Edit #1
Just even more efficient solution would be to binary search the answer as #Spektre suggested. It is known that x2 is increasing function.
function squareroot(number) {
var lo = 0, hi = number;
while(lo <= hi) {
var mid = Math.floor((lo + hi) / 2);
if(mid * mid > number) hi = mid - 1;
else lo = mid + 1;
}
return hi;
}
This algo has O(log(number)) running time complexity.
The stuff that you try to do is called numerical methods. The most rudimentary/easy numerical method for equation solving (yes, you solve an equation x^2 = a here) is a Newtons method.
All you do is iterate this equation:
In your case f(x) = x^2 - a and therefore f'(x) = 2x.
This will allow you to find a square root of any number with any precision. It is not hard to add a step which approximate the solution to an integer and verifies whether sol^2 == a
function squareRoot(n){
var avg=(a,b)=>(a+b)/2,c=5,b;
for(let i=0;i<20;i++){
b=n/c;
c=avg(b,c);
}
return c;
}
This will return the square root by repeatedly finding the average.
var result1 = squareRoot(25) //5
var result2 = squareRoot(100) //10
var result3 = squareRoot(15) //3.872983346207417
JSFiddle: https://jsfiddle.net/L5bytmoz/12/
Here is the solution using newton's iterative method -
/**
* #param {number} x
* #return {number}
*/
// newstons method
var mySqrt = function(x) {
if(x==0 || x == 1) return x;
let ans, absX = Math.abs(x);
let tolerance = 0.00001;
while(true){
ans = (x+absX/x)/2;
if(Math.abs(x-ans) < tolerance) break;
x = ans;
}
return ans;
};
Separates Newton's method from the function to approximate. Can be used to find other roots.
function newton(f, fPrime, tolerance) {
var x, first;
return function iterate(n) {
if (!first) { x = n; first = 1; }
var fn = f(x);
var deltaX = fn(n) / fPrime(n);
if (deltaX > tolerance) {
return iterate(n - deltaX)
}
first = 0;
return n;
}
}
function f(n) {
return function(x) {
if(n < 0) throw n + ' is outside the domain of sqrt()';
return x*x - n;
};
}
function fPrime(x) {
return 2*x;
}
var sqrt = newton(f, fPrime, .00000001)
console.log(sqrt(2))
console.log(sqrt(9))
console.log(sqrt(64))
Binary search will work best.
let number = 29;
let res = 0;
console.log((square_root_binary(number)));
function square_root_binary(number){
if (number == 0 || number == 1)
return number;
let start = 0;
let end = number;
while(start <= end){
let mid = ( start + end ) / 2;
mid = Math.floor(mid);
if(mid * mid == number){
return mid;
}
if(mid * mid < number){
start = mid + 1;
res = mid;
}
else{
end = mid - 1;
}
}
return res;
}
If you analyze all natural numbers with their squares you might spot a pattern...
Numbers Squares Additives
1 1 3
2 4 5
3 9 7
4 16 9
5 25 11
6 36 13
7 49 15
Look at the first row in the squares column (i.e 1) and add it with the first row in the additives column (ie. 3). You will get four which is in the second row of the squares column.
If you keep repeating this you'll see that this applies to all squares of natural numbers. Now if you look at the additives column, all the numbers below are actually odd.
To find the square root of a perfect square you should keep on subtracting it with consecutive odd numbers (starting from one) until it is zero. The number of times it could be subtracted is the square root of that number.
This is my solution in typescript...
function findSquareRoot(number: number): number {
for (let i = 1, count = 0; true; number -= i, i += 2, count++) {
if (number <= 0) {
return number === 0 ? count : -1; // -1 if number is not a perfect square
}
}
}
Hopefully this has better time complexity :)
I see this solution on Github which is the much better and easiest approach to take a square root of a number without using any external library
function TakingPerfectSquare(Num) {
for (var i = 0; i <= Num; i++) {
var element = i;
if ((element == element) && (element*element == Num)) {
return true;
}
}
return false;
}
console.log(TakingPerfectSquare(25));

Function to determine largest prime factor

I am trying to write a function in JS that returns a number's maximum "prime" factor. For example, if I ran maxPrimeFactor(57), I should return a 19. However, my function only works part of the time. I have written a helper function called isPrime that returns a boolean that indicates whether a given number is prime.
Can anyone spot-check my logic and give me pointers as to where I may be going wrong/how I can improve my algorithm and implementation? Any help is appreciated.
function isPrime(n){
var flag = true;
for (var i = 2; i < n / 2; i++) {
if (n % i == 0) {
flag = false;
return flag;
}
}
return flag;
}
function maxPrimeFactor (n) {
var max = 1;
for (var i = 1; i <= n/2; i++) {
if (n % i == 0 && isPrime(i)) {
max = i;
}
}
return max;
}
1 is not prime, so if you pass 1 to the function it will return 1 as the max prime factor which is incorrect. Perhaps a check returning a value like NaN or undefined may be helpful to prevent invalid values, this depends on if you need to limit the scope of the inputs.
if (n < 2) {
return NaN;
}
You also need to consider the case for when n is prime. A possible way around this more efficiently would be to initialize max to n, and then if max is never set again, the max prime is n.
function maxPrimeFactor (n) {
var max = n;
for (var i = 2; i <= n/2; i++) {
if (n % i == 0 && isPrime(i)) {
max = i;
}
}
return max;
}
Since the algorithm only cares about the greatest prime factor, if you start counting down from n/2, you can further optimize the function to return the first prime factor that is found, otherwise return the number.
As the local var flag in isPrime() isn't making the code more readable or functional I would remove it . (Also, no need to loop to n/2 as no number has a prime greater than it's square root);
function isPrime(n){
for (var i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
I give U a code written in C++ below:
#include <cstdio>
#include <cmath>
int max(int x, int y)
{
return x > y ? x : y;
}
int maxPrime(int x)
{
int mx = -1;
int curX = x;
/*i * i <= x is correct, because there is only one prime factor larger than
Sqrt(x), it's power must be 1, and actually it is curX after this loop, because
all prime factor less or equal than Sqrt(x) is eliminated.*/
for(int i = 2; i * i <= x; ++i)
{
while(curX % i == 0)
{
/*Here i must be a prime. consider Prime factorization
x = p1^q1 * p2^q2 * p3^q3...(p1<p2<p3...)
the first number that satisfied x % i == 0 must be p1, it's prime!
and p2 > p1 so I can continue to enumerate i, don't need to reset i to 2.
curX = x/(p1^q1 * p2^q2 * ... * pj^qj) and i = p[j+1]
*/
curX /= i, mx = max(i, mx);
}
}
return max(mx, curX);
}
int main()
{
int n;
scanf("%d", &n);
//I suppose n is positive
if(n == 1) //1 is not prime
printf("No solution\n");
else
printf("%d\n", maxPrime(n));
return 0;
}
This code reaches a worst case running time O(Sqrt(n))
And your code is wrong, because when n is a prime, your code cannot get the right answer.
And your code's efficiency is not good.
If you want a faster code, you can learn Pollard Rho or SQUFOF.

Categories

Resources