Function to determine largest prime factor - javascript

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.

Related

Is finding the factorial of 5000 possible in 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));

how to make a script to print out all prime numbers in js

I want to know how I can improve my code by helping it find out what number is prime and what is not. I was thinking that I would divide a number by a number and then if it is a decimal number then it is prime,
I want it to have a loop to check every number 1 to 100 and see if it is a prime number
This is what I have so far:
for(let i = 1; i <= 100; i++) {
if(i == 1) {
}else if(i == 2) {
console.log(`${i} is a prime number`);
}else if(i >= 3){
x = i / 2;
tf = Number.isInteger(x);
if(tf == false && i >= 3) {
console.log(`${i} is a prime number`);
}
}
}
and so far it outputs 1 2 and all the odd numbers.
Create a function to test whether a number is prime or not (divisible only by 1 and itself). Then call this function inside the loop on each number.
function isPrimeNumber(no) {
if (no < 2) {
return false;
}
for (let i = 2; i < no; i++) {
if (no % i == 0) {
return false;
}
}
return true;
}
for (let i = 1; i <= 100; i++) {
if (isPrimeNumber(i)) {
console.log(i);
}
}
var numbers = new Array(101).fill(0).map((it, index) => index);
var halfWay = Math.floor(numbers.length / 2);
for (let i = 2; i <= halfWay; i++) {
if (!numbers[i]) continue;
for (let j = 2; j * i < numbers.length; j++) {
console.log(`${i} * ${j} = ${i * j}`);
numbers[j * i] = null;
}
}
console.log(numbers.filter(it => it));
Here is an attempt to mathematically find numbers between 1-100 that are primes.
Fill an array of numbers 0-100
For every number (starting at 2), multiply it by itself and all numbers after it, up to half of the array
For every computed number, remore it from the array, as it is not a prime
At the end, filter out all numbers that are null
As Taplar stated primes are numbers that only divide by the number itself and 1.
As far as improving your code. I would say you want to eliminate as many possible numbers with the fewest questions.
An example would be is the number even and not 2 if so it is not prime? The interesting part of this question you eliminate dividing by all even numbers as well. This instantly answers half of all possible numbers and halves the seek time with the ones you need to lookup.
So what would this look like?
function isPrime(num) {
// Check it the number is 1 or 2
if (num === 1 || num === 2) {
return true
}
// Check if the number is even
else if (num % 2 === 0) {
return false;
}
// Look it up
else {
// Skip 1 and 2 and start with 3 and skip all even numbers as they have already been checked
for (let i = 3; i <= num/2; i+=2) {
// If it divides correctly then it is not Prime
if (num % i === 0) {
return false
}
}
// Found no numbers that divide evenly it is Prime
return true
}
}
console.log('1:', isPrime(1))
console.log('2:', isPrime(2))
console.log('3:', isPrime(3))
console.log('4:', isPrime(4))
console.log('11:', isPrime(11))
console.log('12:', isPrime(12))
console.log('97:', isPrime(97))
console.log('99:', isPrime(99))
console.log('65727:', isPrime(65727))
console.log('65729:', isPrime(65729))

JavaScript: Function not returning largest prime factor

Input: 13195
Expected Result: 29 (largest prime factor of input)
Actual Result: 2639 (largest factor of input, but not a prime number)
I didn't bother with even numbers because the largest prime will either be 2 or some odd prime multiplied by 2 to get the input, so what's the point.
function findPrimeFactor(num) {
let prime;
for (let factor = 3; factor < num; factor += 2) {
if (num % factor === 0) {
for (let i = 3; i < factor; i += 2) {
if (factor % i === 0) {
break;
}
else {
prime = factor;
}
}
}
}
return prime;
}
for reference click here, there was other languages, I done the js one
function findPrimeFactor(num) {
// Initialize the maximum prime factor
// variable with the lowest one
let prime = -1;
// Print the number of 2s
// that divide n
while (num % 2 === 0) {
prime = 2;
num = num / 2;
}
// n must be odd at this point,
// thus skip the even numbers
// and iterate only for odd
// integers
for (let factor = 3; factor <= Math.sqrt(num); factor += 2) {
while (num % factor === 0) {
prime = factor;
num = num / factor;
}
}
// This condition is to handle
// the case when n is a prime
// number greater than 2
if (num>2)
prime = num;
return prime;
}
The problem of your code is in the else block. Where every time the program flow enters that block, you replace the prime value with factor value. The answer is to adding an extra temporary variable and in the else block, replacing the value of that.
I did it for you in below code:
function findPrimeFactor(num) {
let prime;
let temp = 3; // Default value for numbers those their largest prime factor is 3
for (let factor = 3; factor < num; factor += 2) {
if (num % factor === 0) {
for (let i = 3; i < factor; i += 2) {
if (factor % i === 0) {
temp = prime; // This value is not prime, so we should not replace the value of prime variable with it.
break;
}
else {
temp = factor; // This factor could be prime. We save it in the temp. If the for loop never meets the upper if block, so this is prime and we can have it.
}
}
prime = temp; // temp value now is a prime number. so we save it to prime variable
}
}
return prime;
}
I just corrected your code behavior and don't add extra behavior to it.
Hope this helped you.

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));

How to avoid this bad for loop?

I'm trying to loop through a big number (6 billion to be exact), but I can't because my computer freezes. How can I work my way around this. I'm supposed to find the largest prime factor of 600851475143.
function prime(n) {
if (n === 1 || n === 2) return false;
if (n % 2 === 0 || n % 3 === 0) return false;
return true;
}
var n = 600851475143;
for (var i = 1, c = []; i < n; i++) {
if ((n % i === 0) && prime(i)) {
c.push(i);
}
}
I'm done with it yet. I'm storing the primes in an array.
Your prime() function doesn't do what the name says it should. There are many efficient ways of factoring primes, try this one for example:
var x = 600851475143;
var i = 2;
var sk;
while(i <= x)
{
while (x % i == 0)
{
sk = i;
x = x / i;
}
i++;
}
console.log(sk);
Output: 6857
This page has another (view source) function for factoring.
That prime function doesn't returns prime numbers only, but all those positive integers that aren't 1 or divisible by 2 and 3.
Let's see the whole algorhythm again. First of all, notice that you don't need to iterate through n, you can stop at its square root (think about it).
var divs = [];
if (!(n & 1)) { // Checking if n is even, using faster bit operators
divs.push(2);
while (!(n & 1)) n >>= 1;
}
var d = 3, l = Math.sqrt(n);
while (d < l) {
if (!(n % d)) {
divs.push(d);
while (!(n % d)) n /= d;
l = Math.sqrt(n);
}
d += 2; // No even numbers except 2 are prime, so we skip them
}
if (n !== 1) divs.push(n);
Now divs[divs.length - 1] contains your largest prime divisor of n, and divs all the prime factors.

Categories

Resources