I intend to find the largest prime factor of a number n in Javascript. However, i think this code is to slow or could be sortened, but i dont see how.
The point would be to display the last element of the arrayfactors, which would be the largest factor. Anyone have any tips on how I could shorten this?
The problem is that my browser notifies me the page is taking too long to respond for a 12 digit number. Should I perhaps not use an array?
function biggest(n) {
// Makes a list of primes smaller than n
var primes = [2];
for (i=3; i < n ; i++) {
var j=0;
while (j<primes.length)
{ var quotient = i/primes[j];
if (quotient !== Math.floor(quotient))
{var hasDivisor = false;
j++;
}
else
{var hasDivisor = true;
j=primes.length+1;
}
}
if (hasDivisor == false)
{primes.push(i);}
}
// Makes a list of factors
var factors = [];
for (i=0; i<primes.length; i++) {
var quotient = n/primes[i];
if (quotient==Math.floor(quotient)) {
factors.push(primes[i]);}
}
if (factors.length==0) {
factors.push(1);
}
items.push("De biggest factor is "+ factors[factors.length-1] +"!");
}
You only need a list of primes up to the square root of n, because if n = p * q, one or the other of p or q must be less than the square root of n (except when n is a perfect square). And instead of computing the primes by iterating over all possible divisors, it is much faster to use the Sieve of Eratosthenes; in pseudocode:
function primes(n)
ps := []
sieve := makeArray(2..n, True)
for p from 2 to n
when sieve[p]
append p to ps
for i from p*p to n step p
sieve[i] := False
return ps
Related
function isPrime(n)
{
if (n < 2)
return false;
let max = sqrt(n);
for(let i = 2; i <= max; i++)
{
if (n % i === 0)
return false;
}
return true;
}
Why does this code block use the square root of the number to be checked as the index of the loop to be run thus making i, the square root of the number in question, to go no higher than say a quarter responses. Are none of the numbers above the square root of n capable of diving evenly into the number? Even big ones into the thousands.
I have written the function which finds largest prime factor of some number. This function works but the problem is that it is too slow. e.g when I enter 600851475143 as a parameter, the process of finding largest prime factor lasts too long. How can I modify it so that it works faster?
Here is my code:
class test {
static addArray(someArray, member) {
for (var i = 0; i <= someArray.length; i++) {
if (i == someArray.length) {
someArray[i] = member;
return someArray;
}
}
}
static someLength(someArray) {
var i = 0;
while (someArray[i] !== undefined) {
var lastItem = i;
i++;
}
return i;
}
static testPrime(i) {
for (var k=2; k < i; k++) {
if (i % k == 0) {
return false;
}
}
return true;
}
}
var primeArray = [];
function largestPrime(n) {
for (var i=2; i < n; i++) {
//var k = n / i;
if (n % i == 0 && test.testPrime(i) == true) {
test.addArray(primeArray, i);
n == n / i;
}
}
return primeArray[test.someLength(primeArray) - 1];
}
document.write(largestPrime(600851475143));
Alright, before we go into that, let's get a little bit of theory sorted. The way you measure the time a particular piece of code takes to run is, mathematically, denoted by the O(n) notation (big-o notation) where n is the size of the input.
Your test prime function is of something called linear complexity meaning that it'll become linearly slow as the size of n (in this case, your number input) gets large.
For the number 15, the execution context is as follows:
15 % 2 == 0 (FALSE)
15 % 3 == 0 (TRUE)
...
15 % 14 == 0 (FALSE)
This means that for the number 100, there will be 98 (2 - 99) steps. And this will grow with time. Let's take your number into consideration: 600851475143. The program will execute 600851475143; the for-loop will get triggered 600,851,475,141 times.
Now, let's consider a clock cycle. Say each instruction takes 1 clock cycle, and a dumbed down version of your loop takes 2, the number 600851475143 will execute 1,201,702,950,286 times. Consider each clock cycle takes 0.0000000625 seconds (for a 16-MHz platform such as the Arduino), the time taken by that code alone is:
0.0000000625 * 1201702950286 = ~75,106 seconds
Or around 20 hours.
You see where I am going with this.
Your best best to get this program to work faster is to use a probabilistic test and confirm your findings using this number (or a BigInteger variant thereof).
Your approach is more linear, in the sense that the number of iterations for the for-loop to check for primality increases with an increasing number. You can plot the CPU cycle time along with the number and you'll realize that this is a rather inefficient way to do this.
I have discrete mathematics at my Uni, so just a word of warning - primality tests and their variants get really messy as you get into the utopia of faster and faster tests. It's a path filled with thorns of mathematics and you should have a seat belt while riding through the jungle! ;)
If you need more information on this, I would be glad to assist! I hope this helped! :)
Experienced codefighters, i have just started using Codefight website to learn Javascript. I have solved their task but system does not accept it. The task is to sum all integers (inidividual digit) in a number. For example sumDigit(111) = 3. What is wrong with my code? Please help me.
Code
function digitSum(n) {
var emptyArray = [];
var total = 0;
var number = n.toString();
var res = number.split("");
for (var i=0; i<res.length; i++) {
var numberInd = Number(res[i]);
emptyArray.push(numberInd);
}
var finalSum = emptyArray.reduce(add,total);
function add(a,b) {
return a + b;
}
console.log(finalSum);
//console.log(emptyArray);
//console.log(res);
}
Here's a faster trick for summing the individual digits of a number using only arithmetic:
var digitSum = function(n) {
var sum = 0;
while (n > 0) {
sum += n % 10;
n = Math.floor(n / 10);
}
return sum;
};
n % 10 is the remainder when you divide n by 10. Effectively, this retrieves the ones-digit of a number. Math.floor(n / 10) is the integer division of n by 10. You can think of it as chopping off the ones-digit of a number. That means that this code adds the ones digit to sum, chops off the ones digit (moving the tens digit down to where the ones-digit was) and repeats this process until the number is equal to zero (i.e. there are no digits left).
The reason why this is more efficient than your method is that it doesn't require converting the integer to a string, which is a potentially costly operation. Since CodeFights is mainly a test of algorithmic ability, they are most likely looking for the more algorithmic answer, which is the one I explained above.
function primesuntil(n) {
var primes = [2];
for (i=3; i < n ; i++) {
var j=0;
while (j<primes.length) {
var quotient = i/primes[j];
if (quotient !== math.floor(quotient) {
var hasDivisor = false;
j++;
}
else {
var hasDivisor = true;
j=primes.length+15;
}
}
if (hasDivisor == false)
{primes.push(i);}
else
{var nothing = 3;}
}
printarray(primes);
}
I want to run this code in JavaScript, which is supposed to print all prime numbers smaller than n, but for some reason it will not run. Have I made a mistake somewhere? When i comment this function out the rest of the code does run.
What the code should do is divide all numbers in the array "primes", and if at some point the quotient equals the 'floor' of that number (meaning it is divisable by the number from the array), hasdivisor becomes true and the number is not added to the array of primes. also, j stops counting (we don't have to divide by the other primes anymore, we know it's not prime). If it doesn't divide any prime numbers smaller than itself, it is prime, so it is added to the list. What's wrong?
It is if (quotient !== math.floor(quotient)) an extra ), and it is Math.floor, uppercase M.
You have a missing closing parentheses in this line :
if (quotient !== math.floor(quotient)) {
I'm doing the 3rd project euler question right now. So far I've figured out how to solve the problem which is finding the largest prime factor of 600851475143.
I've wrote a small bit of code that can place all the prime factors of a number into an array. The problem I'm having is the number may be too large to compute. I've used other large numbers (not as large as this one) and they've worked fine but this one just freezes up the page like it's in an endless loop. Here's the code:
var primes = [];
function factor (largestNumber) {
var a = largestNumber;
var b = 2;
while (b < largestNumber) {
if (a % b == 0) {
a /= b;
primes.push(b);
b = 2;
} else {
b++;
}
}
}
factor(600851475143);
console.log(primes);
Your algorithm is not optimal.
function factor(largestNumber) {
var primes = []; // using local value
var a = largestNumber;
var b = 2;
while (b <= Math.floor(Math.sqrt(a))) { // we do not need to check whole number
// over and over again.
// We could check to a only
// or even to sqrt(a) only
if (a % b == 0) {
a /= b;
primes.push(b);
// there is no reason to reset value
} else {
b++;
}
}
primes.push(a); // rest number would be always prime
return primes;
}
console.log(factor(600851475143));
This may be a useful way, split the largest primary factor into 3 part.
Cut the largest Num into 2 close num eg 40 => 5 * 8
Get the bigger num(8) and find out all the prime num small than it. Storage into Array.
Use a loop to get the largest prime factor.
That's all, I will try it tonight. If I make it I will add the jsfiddle addr. : )