Find the largest prime factor with Javascript - javascript

Thanks for reading. Pretty new to Javascript and programming in general.
I'm looking for a way to return the largest prime factor of a given number. My first instinct was to work with a while loop that counts up and finds prime factors of the number, storing the factors in an array and resetting each time it finds one. This way the last item in the array should be the largest prime factor.
var primerizer = function(input){
var factors = [];
var numStorage = input
for (x=2; numStorage != 1; x++){ // counter stops when the divisor is equal to the last number in the
// array, meaning the input has been fully factorized
if (result === 0) { // check if the number is prime; if it is not prime
factors.push(x); // add the divisor to the array of prime numbers
numStorage = numStorage/x // divide the number being calculated by the divisor
x=2 // reset the divisor to 2 and continue
};
};
primeFactor = factors.pop();
return primeFactor;
}
document.write(primerizer(50))
This only returned 2, undefined, or nothing. My concern was that the stop condition for the for loop must be defined in terms of the same variable as the start condition, so I tried it with a while loop instead.
var primerizer = function(input){
var factors = [];
var numStorage = input
x=2
while (numStorage != 1){
var result = numStorage%x;
if (result === 0) {
factors.push(x);
numStorage = numStorage/x
x=2
}
else {
x = x+1
}
}
return factors.pop();
}
document.write(primerizer(50)
Same problem. Maybe there's a problem with my syntax that I'm overlooking? Any input is much appreciated.
Thank you.

The shortest answer I've found is this:
function largestPrimeFactor(n){
var i=2;
while (i<=n){
if (n%i == 0){
n/=i;
}else{
i++;
}
}
console.log(i);
}
var a = **TYPE YOUR NUMBER HERE**;
largestPrimeFactor(a)

You can try with this
var x = 1, div = 0, primes = [];
while(primes.length != 10001) {
x++;
for(var i = 2; i < x && !div; i++) if(!(x % i)) div++;
if(!div) primes.push(x); else div = 0;
}
console.log(primes[primes.length-1]);
or this: (This solution uses more of your memory)
var dont = [], max = 2000000, primes = [];
for (var i = 2; i <= max; i++) {
if (!dont[i]) {
primes.push(i);
for (var j = i; j <= max; j += i) dont[j] = true;
}
}
console.log(primes);

here is my own solution.
//function
function largestPrimeFactor (num) {
//initialize the variable that will represent the divider
let i = 2;
//initialize the variable that will represent the quotient
let numQuot = num;
//array that will keep all the dividers
let primeFactors = [];
//execute until the quotient is equal to 1
while(numQuot != 1) {
/*check if the division between the number and the divider has no reminder, if yes then do the division keeping the quotient in numQuot, the divider in primeFactors and proceed to restart the divider to 2, if not then increment i by one an check again the condition.*/
if(numQuot % i == 0){
numQuot /= i;
primeFactors.push(i);
i = 2;
} else {
i++;
}
}
/*initialize the variable that will represent the biggest prime factor. biggest is equal to the last position of the array, that is the biggest prime factor (we have to subtract 1 of .length in order to obtain the index of the last item)*/
let biggest = primeFactors[primeFactors.length - 1];
//write the resutl
console.log(biggest);
}
//calling the function
largestPrimeFactor(100);

<script>
function LPrimeFactor() {
var x = function (input) {
var factors = [];
var numStorage = input;
x = 2;
while (numStorage != 1) {
var result = numStorage % x;
if (result === 0) {
factors.push(x);
numStorage = numStorage / x;
x = 2;
}
else {
x = x + 1;
}
}
return factors.pop();
}
document.write(x(50));
}
</script>
<input type="button" onclick="LPrimeFactor();" />
Here is an example i tried with your code

Here is the solution I used that should work in theory... except for one small problem. At a certain size number (which you can change in the code) it crashes the browser due to making it too busy.
https://github.com/gordondavidescu/project-euler/blob/master/problem%203%20(Javascript)
Adding the code inline:
<p id="demo">
</p>
<script>
function isPrime(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
}
function biggestPrime(){
var biggest = 1;
for(var i = 600851470000; i < 600851475143; i++){
if (isPrime(i) != false)
{
biggest = i;
}
document.getElementById("demo").innerHTML = biggest;
}
}
biggestPrime();
</script>
</p>

<script>
//Finds largest prime factor
find = 2165415 ; // Number to test!
var prime = 0;
loop1:
for (i = 2; i < find; i++){
prime = 0;
if (find%i == 0){
document.write(find/i);
for (j = 2; j < (find / i); j++){
if ((find / i )%j == 0){
document.write(" divides by "+j+"<br>");
prime = prime + 1;
break;
}
}
if (prime == 0){
document.write("<br>",find/i, "- Largest Prime Factor")
prime = 1;
break;
}
}
}
if (prime==0)
document.write("No prime factors ",find," is prime!")

Related

Cheking if it's a prime number with JS

I'm first trying to push only prime numbers (without 2) to an array and then sum them all but getting undefined.
I've been working on this for long days, I'd appreciate if anyone could help me.
let letsCheck = () => {
let ourList = []
let sum = 0
for(let i = 2; i <= 50; i++) {
if(i % 2 !== Number.isInteger()) {
ourList.push(Number(i))
}
}
for(let prime in ourList) {
sum += ourList[prime]
}
}
First of all, You are not checking prime but checking odd numbers by % operator.
Second, you are checking Number.isNumber function which will return the boolean so, the comparison have some issues.
Here is one solution which may help.
let letsCheck = () => {
let ourList = []
let sum = 0
for(let i = 3; i <= 50; i++) {
if(isPrimeNumber(i)) {
ourList.push(Number(i))
}
}
for(let prime in ourList) {
sum += ourList[prime]
}
}
const isPrimeNumber = number => {
for(let i = 2; i <= Math.ceil(number/2); i++) {
if(number % 2 === 0) {
return false;
}
}
return true;
}
From, your code, it was more likely for obtaining odd/even numbers instead of prime numbers.
Prime numbers are whole numbers greater than 1, that have only two factors – 1 and the number itself
Odd numbers are the numbers that doesn't have 2 as its factor, and will have remainder = 1 if it gets divided by 2.
Then, as the basic programming math, the mod works like multiplication/add/subtraction that if both operators/numbers are Integer, the result would be Integer. The mod operation is basically for obtaining the remainders from the division, i.e. 5 / 2 = 2, with remainders = 1, thus 5 % 2 = 1.
And, in the looping, the i is already a number, so pushing the Number(i) is equivalent with pushing i alone. If you just want to get the sum, the array is not necessary there and should be just removed. You can get the sum by accumulate it into the sum variable.
Thus, if you wish to get the sum of odd numbers in the range [2,50], it should be:
let letsCheck = () => {
let sum = 0
for(let i = 2; i <= 50; i++) {
if(i % 2 !== 0) {
sum += i;
}
}
console.log(sum);
}
letsCheck();
And if you wish to get the prime numbers from 0 to 50 excluding 2, it should be:
function isPrimeExclude2(num) {
if(num <= 2) return false;
for(let i=2; i*i <= num; i++){
if (num % i == 0) return false;
}
return true;
}
let letsCheck = () => {
let sum = 0
for(let i = 2; i <= 50; i++) {
if(isPrimeExclude2(i)) {
sum = sum + i;
}
}
console.log(sum);
}
letsCheck();

My code crashes javascript console

My code is freezing Chrome (and Firefox), won't execute on Coderbyte console but when I submit the code as an answer to the exercise, it does take.
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
while (num !== 6174) {
num = numReversed - numOrdered;
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);
Why is it crashing? How can I prevent it?
Thank you guys!
the actual problem is the second while loop:
while (num !== 6174) {
num = numReversed - numOrdered;
tries += 1;
}
Removing it, your code doesn't hang the browser:
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
return tries;
};
console.log(KaprekarsConstant(8593));
You need to revisit the logic in the second loop so that it doesn't become infinite.
The second loop makes your code to hang up.Try this. I have made some changes.
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
while (num !== 6174) {
var arr = [];
while(num >0){
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
num = numReversed - numOrdered;
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);
The while loop in the post keeps calculating the same value for num, so it it is not immediately 6174, the loop continues forever.
Basically the code is not following the algorithm for demonstrating Kaprekar's constant as shown on Wikipedia:
pad numbers of less than 4 digits with leading zeroes,
subtract the smaller number from the larger of { number, number with reversed digits), and
repeat from the step of extracting digits from the latest subtraction result.
Spoiler alert - here's a working example of a recursive function with the extra pieces of logic:
"use strict";
function KaprekarsConstant(num, tries=0) {
if( num == 6174) // Kaprekar's constant.
return tries;
if( num == 0) // degenerate case, digits are the same
return -tries;
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
while( arr.length<4) { // leading zeroes as required
arr.unshift(0);
}
arr.sort();
var numOrdered = Number(arr.join(''));
var numReversed = Number(arr.reverse().join(''));
num = Math.abs( numOrdered - numReversed) // larger - smaller
return KaprekarsConstant( num, ++tries); // try again
};
// and test
function test() {
var num = Number(input.value);
if( Number.isNaN(num) || num < 1 || num > 9999) {
throw new Error("Enter number between 1 and 9999");
}
console.log("Tries = %s", KaprekarsConstant(num) );
}
<label> Enter 1 to 4 digit number: <input type="text" id="input"></label><br>
<button type="button" onclick="test()">Calculate tries</button>
While the answers do address your question, the solutions and the code are missing the part about leading zeros as in wiki Kaprekar's constant
and the whole solution is very simple
function KaprekarsConstant(num)
{
var tries=0;
var numOrdered =0;
var numRevesed=0;
while(num!=6174)
{
numOrdered=("0000" + num).substr(-4,4).split("").sort().join("");
numRevesed=numOrdered.split("").reverse().join("");
num = numRevesed-numOrdered;
tries+=1;
}
return tries;
}
KaprekarsConstant(8593);
To the reason for 'Why is it crashing?', its maybe due to Infinite Loop .
The response I got when I try to run your code
Possible infinite loop detected.
Error: Infinite loop
at KaprekarsConstant (script 19:68)
at script 27:1
Thank you everybody for the answers!!
Thanks to #Jaromanda X I realise the last while loop was infinite, since
num = numOrdered - numReversed;
will always be the same.
I realised I had to re-arrange the numbers every time so I create a function for that and incorporate it into the while loop.
I also added a bit of code from #traktor53 to add the leading zeros in case of a number with less than 4 digits.
And to finish I declare
var tries = 0;
inside the function so it will start from zero in each run.
.
.
Final result:
var numOrdered = 0;
var numReversed = 0;
function KaprekarsConstant(num) {
var tries = 0;
function order(num) { // function to order the numbers
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
while(arr.length<4) { // leading zeroes as required
arr.unshift(0);
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
}
while (num !== 6174) {
order(num);
num = Math.abs(numOrdered - numReversed); // larger - smaller
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);

Better solution for finding numbers with exactly 3 divisors

I was studying some programming and I found an exercise to write an algorithm finding "threesome numbers" (numbers that are divisible by exactly 3 numbers). I wrote this:
function threesomeNumber(N) {
var found = 0;
var i = 1;
var numberOfDivisions = 1;
while (found < N) {
for (var j = 2; j <= i; j++) {
if (i % j === 0) {
numberOfDivisions++;
}
}
if (numberOfDivisions === 3) {
found++;
console.log(found + " = " + i);
}
numberOfDivisions = 1;
i++;
}
}
The problem is it's running kinda slow and I was wondering if it can be done quicker. Does anybody know of a more optimized solution? I want it to find N consecutive threesome numbers.
The only threesome numbers are squares of primes (divisors 1, p, p^2). Just do Erathostenes and return the squares.
Proof: If it has an odd number of divisors it is known to be a square. Since 1 and n^2 are always divisors of n^2, we may only have one more divisor, i.e. n. Any divisor of n would be another divisor of n^2, therefore n is prime.
Example (based on given code):
function threesomeNumber(N) {
var found = 0;
var i = 2;
var prime = true;
while (found < N) {
// Naive prime test, highly inefficient
for (var j = 2; j*j <= i; j++) {
if (i % j === 0) {
prime = false;
}
}
if (prime) {
found++;
console.log(found + " = " + (i*i));
}
prime = true;
i++;
}
}
You could implement an algorithm based on the sieve of Eratosthenes. The only change is that you don't mark the multiples of found primes, but the multiples of found numbers which have at least 3 divisors. The reason is that you can be sure that the multiples of these numbers have more than 3 divisors.
EDIT: Hermann's solution is the best for "threesomes". My idea is more general and applicable for "N-somes".
A more optimized solution is to find the first N Prime numbers and square them. The idea behind that is that prime numbers are divisible by only two numbers. So numbers divisible by only three numbers have an extra divider which must be its square root. It must be a prime so it doesn't add extra divider to the main number dividers.
function threesomeNumber(N){
return firstPrimes(N).map(function(x){return x*x})
}
Where firstPrimes is a function that returns the first N primes.
Here's a simple one:
function threesomeNumber(N)
{
var found = 0;
var i = 1;
var numberOfDivisions = 1;
while(found < N)
{
for(var j = 2; j <= i; j++)
{
if(i % j === 0)
numberOfDivisions++;
// Stop trying if more that 3 Divisions are Found
if(numberOfDivisions > 3)
break;
}
if(numberOfDivisions === 3)
{
found++;
console.log(found + " = " + i);
}
numberOfDivisions = 1;
i++;
}
}
Here is one with time complexity= O(N^(1/2)*N^(1/4))
public int exactly3Divisors(int N)
{
int count=0,flag=0;
for(int i=2;i*i<=N;i++){
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=1;
break;
}
}
if(flag==0){
count++;
}
flag=0;
}
return count;
}
int threesomeNumber(int N)
{
//Your code here
int num =0;
bool prime = true;
for(int i=2; i<=sqrt(N); i++)
{
for(int j=2; j<i; j++)
{
if(i % j == 0)
{
prime = false;
break;
}
}
if(prime)
{
num++;
}
prime = true;
}
return num;
}

Is there any way to increase performance for this for loop in JS?

Im trying to solve project euler 10 problem (find the sum of all the primes below two million), but the code takes forever to finish, how do i make it go faster?
console.log("Starting...")
var primes = [1000];
var x = 0;
var n = 0;
var i = 2;
var b = 0;
var sum = 0;
for (i; i < 2000000; i++) {
x = 0;
if (i === 2) {
primes[b] = i
sum += primes[b];
console.log(primes[b]);
b++;
}
for (n = i - 1; n > 1; n--) {
if (i % n === 0) {
x++;
}
if (n === 2 && x === 0) {
primes[b] = i;
sum += primes[b];
console.log(primes[b]);
b++;
}
}
}
console.log(sum)
The biggest super easy things you can do to make this a lot faster:
Break out of the inner loop when you find a divisor!
When you're checking for primality, start with the small divisors instead of the big ones. You'll find the composites a lot faster.
You only have to check for divisors <= Math.sqrt(n)
You only need to check prime divisors. You have a list of them.
Process 2 outside the loop, and then only do odd numbers inside the loop: for(i=3;i<2000000;i+=2)
Here is another version based on the Sieve of Eratosthenes. It requires much more memory but if this does not concern you it's also pretty fast.
// just a helper to create integer arrays
function range(from, to) {
var numbers = [];
for (var i=from ; i<=to ; i++) {
numbers.push(i);
}
return numbers;
}
function primesUpTo(limit) {
if (limit < 2) return [];
var sqrt = Math.floor(Math.sqrt(limit));
var testPrimes = primesUpTo(sqrt);
var numbers = range(sqrt+1, limit);
testPrimes.forEach(function(p) {
numbers = numbers.filter(function(x) { return x % p > 0 });
});
return testPrimes.concat(numbers);
}
var primes = primesUpTo(2000000);
var sum = primes.reduce(function(acc, e) { return acc + e });
Since you keep an array of your primes anyway, you can split the process in two steps:
Generating the primes up to your limit of 2 million
and summing up.
As pointed out by others, you need only check whether a candidate number is divisable by another prime not larger than the square root of the candidate. If you can write a number as a product of primes, then one of those primes will always be lower than or equal to the number's square root.
This code can be optimized further but it is several orders of magnitude faster than your initial version:
function primesUpTo(limit) {
if (limit < 2) return [];
var sqrt = Math.floor(Math.sqrt(limit));
var testPrimes = primesUpTo(sqrt);
var result = [].concat(testPrimes);
for (var i=sqrt+1 ; i<=limit ; i++) {
if (testPrimes.every(function(x) { return (i % x) > 0 })) {
result.push(i);
}
}
return result;
}
var primes = primesUpTo(2000000);
var sum = primes.reduce(function(acc, e) { return acc + e });

JavaScript Function Arrays

How would I use a function that returns the sum of a given array while getting the sum of the even numbers and sum the odd numbers? I'm not understanding how that is done. Can someone please explain a little more in depth?
Here is my entire code:
function main()
{
var evenNum = 0;
//need a total Even count
var oddNum = 0;
//need a total Odd count
var counter = 1;
var num = 0;
function isOdd(x) {
if ((num % 2) == 0)
{
return false;
}
else
{
return true;
}
}
function isEven(x) {
if ((num % 2) == 0)
{
return false;
}
else
{
return true;
}
}
for (counter = 1; counter <= 100; counter++)
{
num = Math.floor(1 + Math.random() * (100-1));
var total = 0;
for(var j = 0; j < length; j++)
total += a[j];//Array?
console.log(num);
console.log("The count of even number is " + evenNum);
console.log("The count of odd number is " + oddNum);
return 0;
}
main()
If I understand your question correctly, you need a function that returns two values, one for the sum of even numbers and one for the sum of odd numbers. It's not clear if you use even/odd referring to the index of the array or the values in array.
In both cases you can return an object that contains both values:
function sum(array) {
var evenSum = 0;
var oddSum = 0;
...calculate...
var res = {};
res.evenSum = evenSum;
res.oddSum = oddSum;
return res;
}
Hope this will help

Categories

Resources