A faster way to compute the largest prime factorProject Euler #3 - largest prime factorA faster way to compute largest prime factor (Again, but a lot better)Faster way to determine largest prime factorx64 Assembly - checking for largest prime factorProject Euler #3 (Largest prime factor) in SwiftProject Euler 3: Getting the largest prime factor of a numberVery slow Project Euler Q3 (largest prime factor of a large number)Project Euler 3: Largest prime factorLargest prime factor of a given numberProject Euler 3 - Largest prime factorWork out largest prime factor of a numberA faster way to compute largest prime factor (Again, but a lot better)
What is the strongest case that can be made in favour of the UK regaining some control over fishing policy after Brexit?
A question regarding using the definite article
Pressure to defend the relevance of one's area of mathematics
Is GOCE a satellite or aircraft?
When to use 1/Ka vs Kb
Why do Ichisongas hate elephants and hippos?
Does jamais mean always or never in this context?
In the time of the mishna, were there Jewish cities without courts?
Are Boeing 737-800’s grounded?
Given what happens in Endgame, why doesn't Dormammu come back to attack the universe?
Please, smoke with good manners
Pawn Sacrifice Justification
Feels like I am getting dragged in office politics
Reverse the word in a string with the same order in javascript
What does 「再々起」mean?
Weird result in complex limit
How can Republicans who favour free markets, consistently express anger when they don't like the outcome of that choice?
How to determine the actual or "true" resolution of a digital photograph?
Pulling the rope with one hand is as heavy as with two hands?
Phrase for the opposite of "foolproof"
Past Perfect Tense
How can I get precisely a certain cubic cm by changing the following factors?
Stark VS Thanos
Where did the extra Pym particles come from in Endgame?
A faster way to compute the largest prime factor
Project Euler #3 - largest prime factorA faster way to compute largest prime factor (Again, but a lot better)Faster way to determine largest prime factorx64 Assembly - checking for largest prime factorProject Euler #3 (Largest prime factor) in SwiftProject Euler 3: Getting the largest prime factor of a numberVery slow Project Euler Q3 (largest prime factor of a large number)Project Euler 3: Largest prime factorLargest prime factor of a given numberProject Euler 3 - Largest prime factorWork out largest prime factor of a numberA faster way to compute largest prime factor (Again, but a lot better)
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
I am self-learning js and came across this problem(#3) from the Euler Project
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Logic:
Have an array
primes
to store all the prime numbers less thannumber
Loop through the odd numbers only below
number
to check for primes usingi
Check if
i
is divisible by any of the elements already inprimes
.- If yes,
isPrime = false
and break the for loop forj
byj=primesLength
- If not,
isPrime = true
- If yes,
If
isPrime == true
then addi
to the arrayprimes
and check ifnumber%i == 0
- If
number%i == 0%
update the value offactor
asfactor = i
- If
Return
factor
after looping through all the numbers belownumber
My code:
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
It is working perfectly for small numbers, but is quite very slow for 600851475143. What should I change in this code to make the computation faster?
Edit: Updated code based on feedback
javascript beginner programming-challenge time-limit-exceeded primes
New contributor
$endgroup$
add a comment |
$begingroup$
I am self-learning js and came across this problem(#3) from the Euler Project
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Logic:
Have an array
primes
to store all the prime numbers less thannumber
Loop through the odd numbers only below
number
to check for primes usingi
Check if
i
is divisible by any of the elements already inprimes
.- If yes,
isPrime = false
and break the for loop forj
byj=primesLength
- If not,
isPrime = true
- If yes,
If
isPrime == true
then addi
to the arrayprimes
and check ifnumber%i == 0
- If
number%i == 0%
update the value offactor
asfactor = i
- If
Return
factor
after looping through all the numbers belownumber
My code:
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
It is working perfectly for small numbers, but is quite very slow for 600851475143. What should I change in this code to make the computation faster?
Edit: Updated code based on feedback
javascript beginner programming-challenge time-limit-exceeded primes
New contributor
$endgroup$
6
$begingroup$
"//to break the for loop
" Doesn't Javascript have abreak
?
$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
1
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago
add a comment |
$begingroup$
I am self-learning js and came across this problem(#3) from the Euler Project
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Logic:
Have an array
primes
to store all the prime numbers less thannumber
Loop through the odd numbers only below
number
to check for primes usingi
Check if
i
is divisible by any of the elements already inprimes
.- If yes,
isPrime = false
and break the for loop forj
byj=primesLength
- If not,
isPrime = true
- If yes,
If
isPrime == true
then addi
to the arrayprimes
and check ifnumber%i == 0
- If
number%i == 0%
update the value offactor
asfactor = i
- If
Return
factor
after looping through all the numbers belownumber
My code:
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
It is working perfectly for small numbers, but is quite very slow for 600851475143. What should I change in this code to make the computation faster?
Edit: Updated code based on feedback
javascript beginner programming-challenge time-limit-exceeded primes
New contributor
$endgroup$
I am self-learning js and came across this problem(#3) from the Euler Project
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Logic:
Have an array
primes
to store all the prime numbers less thannumber
Loop through the odd numbers only below
number
to check for primes usingi
Check if
i
is divisible by any of the elements already inprimes
.- If yes,
isPrime = false
and break the for loop forj
byj=primesLength
- If not,
isPrime = true
- If yes,
If
isPrime == true
then addi
to the arrayprimes
and check ifnumber%i == 0
- If
number%i == 0%
update the value offactor
asfactor = i
- If
Return
factor
after looping through all the numbers belownumber
My code:
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
It is working perfectly for small numbers, but is quite very slow for 600851475143. What should I change in this code to make the computation faster?
Edit: Updated code based on feedback
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
function problem3(number)
let factor = 1;
let primes = [2]; //array to store prime numbers
for(let i=3; i<number; i=i+2) //Increment i by 2 to loop through only odd numbers
let isPrime = true;
let primesLength= primes.length;
for(let j=0; j< primesLength; j++)
if(i%primes[j]==0)
isPrime = false;
j=primesLength; //to break the for loop
if(isPrime == true)
primes.push(i);
if(number%i == 0)
factor = i;
return factor;
console.log(problem3(600851475143));
javascript beginner programming-challenge time-limit-exceeded primes
javascript beginner programming-challenge time-limit-exceeded primes
New contributor
New contributor
edited Apr 25 at 11:47
Eagle
New contributor
asked Apr 25 at 3:35
EagleEagle
1658
1658
New contributor
New contributor
6
$begingroup$
"//to break the for loop
" Doesn't Javascript have abreak
?
$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
1
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago
add a comment |
6
$begingroup$
"//to break the for loop
" Doesn't Javascript have abreak
?
$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
1
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago
6
6
$begingroup$
"
//to break the for loop
" Doesn't Javascript have a break
?$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
"
//to break the for loop
" Doesn't Javascript have a break
?$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
1
1
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago
add a comment |
4 Answers
4
active
oldest
votes
$begingroup$
There are many questions about Project Euler 3 on this site already. The trick is to pick an algorithm that…
- Reduces
n
whenever you find a factor, so that you don't need to consider factors anywhere near as large as 600851475143 - Only finds prime factors, and never composite factors, so that you never need to explicitly test for primality.
Your algorithm suffers on both criteria: the outer for
loop goes all the way up to 600851475143 (which is ridiculous, because even if you optimistically assume that it takes one nanosecond per loop, that would be 5 minutes), and you're testing each of those numbers for primality (which is incredibly computationally expensive).
$endgroup$
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,divsd
(scalardouble
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.
$endgroup$
– Peter Cordes
Apr 25 at 17:50
add a comment |
$begingroup$
For starters, you only need to check odd numbers (potential primes) below sqrt(X).
If A*B=X, then either A=B and X is a perfect square, so the largest prime dividing A is the largest prime factor.
OR, one of A and B is less than the other, and thus less than the sqrt(X).
Without loss of generality, say A is less than B. Then B would be greater than the sqrt(X), but the largest prime factor in A or B would be the largest prime factor of X.
So, you can start testing B, and just like X, you only need to test numbers less than the sqrt(B), and when testing A those less than the sqrt(A).
You can keep a list of numbers that divide X, I would always try to find a factor of the largest number that divides X: If it is prime, it is the largest prime factor. But if you do find a factor of the largest, get rid of it and replace it with its two factors. Then once again, find the largest factor and prove it is prime or composite.
I would also start your loop for finding a factor "from the bottom", not from the top, to play the odds.
1/3 of all numbers are divisible by 3, 1/5 divisible by 5, etc. You can divide by 2 as many times as possible before beginning. Then keep track of the largest odd number you have tried (prime or not, that will include all primes), so once they fail, you don't need to try them again.
New contributor
$endgroup$
add a comment |
$begingroup$
The first problem is that you are trying to find all prime numbers under number. The number of prime numbers under x is approximately x/ln(x) which is around 22153972243.4 for our specific value of x
This is way too big ! So even if you where capable of obtaining each of these prime numbers in constant time it would take too much time.
This tells us this approach is most likely unfixable.
New contributor
$endgroup$
add a comment |
$begingroup$
You already skip all even numbers.
For the same reason, create code that skips:
- every 3rd #
- every 5th #
- every 7th ... 11th ... 13th, maybe ...
New contributor
$endgroup$
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Eagle is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219063%2fa-faster-way-to-compute-the-largest-prime-factor%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
There are many questions about Project Euler 3 on this site already. The trick is to pick an algorithm that…
- Reduces
n
whenever you find a factor, so that you don't need to consider factors anywhere near as large as 600851475143 - Only finds prime factors, and never composite factors, so that you never need to explicitly test for primality.
Your algorithm suffers on both criteria: the outer for
loop goes all the way up to 600851475143 (which is ridiculous, because even if you optimistically assume that it takes one nanosecond per loop, that would be 5 minutes), and you're testing each of those numbers for primality (which is incredibly computationally expensive).
$endgroup$
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,divsd
(scalardouble
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.
$endgroup$
– Peter Cordes
Apr 25 at 17:50
add a comment |
$begingroup$
There are many questions about Project Euler 3 on this site already. The trick is to pick an algorithm that…
- Reduces
n
whenever you find a factor, so that you don't need to consider factors anywhere near as large as 600851475143 - Only finds prime factors, and never composite factors, so that you never need to explicitly test for primality.
Your algorithm suffers on both criteria: the outer for
loop goes all the way up to 600851475143 (which is ridiculous, because even if you optimistically assume that it takes one nanosecond per loop, that would be 5 minutes), and you're testing each of those numbers for primality (which is incredibly computationally expensive).
$endgroup$
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,divsd
(scalardouble
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.
$endgroup$
– Peter Cordes
Apr 25 at 17:50
add a comment |
$begingroup$
There are many questions about Project Euler 3 on this site already. The trick is to pick an algorithm that…
- Reduces
n
whenever you find a factor, so that you don't need to consider factors anywhere near as large as 600851475143 - Only finds prime factors, and never composite factors, so that you never need to explicitly test for primality.
Your algorithm suffers on both criteria: the outer for
loop goes all the way up to 600851475143 (which is ridiculous, because even if you optimistically assume that it takes one nanosecond per loop, that would be 5 minutes), and you're testing each of those numbers for primality (which is incredibly computationally expensive).
$endgroup$
There are many questions about Project Euler 3 on this site already. The trick is to pick an algorithm that…
- Reduces
n
whenever you find a factor, so that you don't need to consider factors anywhere near as large as 600851475143 - Only finds prime factors, and never composite factors, so that you never need to explicitly test for primality.
Your algorithm suffers on both criteria: the outer for
loop goes all the way up to 600851475143 (which is ridiculous, because even if you optimistically assume that it takes one nanosecond per loop, that would be 5 minutes), and you're testing each of those numbers for primality (which is incredibly computationally expensive).
edited Apr 25 at 16:30
answered Apr 25 at 4:19
200_success200_success
132k20159424
132k20159424
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,divsd
(scalardouble
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.
$endgroup$
– Peter Cordes
Apr 25 at 17:50
add a comment |
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,divsd
(scalardouble
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.
$endgroup$
– Peter Cordes
Apr 25 at 17:50
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
$begingroup$
The "pick an algorithm" link never explains this explicitly; when you start from low numbers you don't need to check the divisors for primality since the divisors of any composite number would already have been divided out. Even if the original number was divisible by 15, it would already have been divided by 3 and 5.
$endgroup$
– JollyJoker
Apr 25 at 8:38
3
3
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
@JollyJoker I kind of mentioned it, without giving away the spoiler: "Bonus question: in the example above, do we still need to test 19 for primality? Why or why not?"
$endgroup$
– 200_success
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
Now I feel like writing a code golfed recursive version, but don't have time...
$endgroup$
– JollyJoker
Apr 25 at 8:43
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
You also test every odd number without explanation, while a naive implementation would test the divisors for primality first. Well, some prefer complete answers, some want the asker to think.
$endgroup$
– JollyJoker
Apr 25 at 8:48
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,
divsd
(scalar double
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.$endgroup$
– Peter Cordes
Apr 25 at 17:50
$begingroup$
Integer division is still very slow compared to other operations, like multiplication. And even on modern x86 CPUs, isn't fully pipelined. (A new division can't start every clock cycle. Like 1 per 6 cycles on Skylake for 32-bit division, or 1 per 21 to 83 cycles for 64-bit division: agner.org/optimize). 1ns is only 4 clocks on a 4GHz CPU. But if we're being very optimistic,
divsd
(scalar double
floating point) has 1 per 4-clock throughput on Skylake, so maybe we could come close if we come up with a way to check if the result of that is an exact integer in only a couple uops.$endgroup$
– Peter Cordes
Apr 25 at 17:50
add a comment |
$begingroup$
For starters, you only need to check odd numbers (potential primes) below sqrt(X).
If A*B=X, then either A=B and X is a perfect square, so the largest prime dividing A is the largest prime factor.
OR, one of A and B is less than the other, and thus less than the sqrt(X).
Without loss of generality, say A is less than B. Then B would be greater than the sqrt(X), but the largest prime factor in A or B would be the largest prime factor of X.
So, you can start testing B, and just like X, you only need to test numbers less than the sqrt(B), and when testing A those less than the sqrt(A).
You can keep a list of numbers that divide X, I would always try to find a factor of the largest number that divides X: If it is prime, it is the largest prime factor. But if you do find a factor of the largest, get rid of it and replace it with its two factors. Then once again, find the largest factor and prove it is prime or composite.
I would also start your loop for finding a factor "from the bottom", not from the top, to play the odds.
1/3 of all numbers are divisible by 3, 1/5 divisible by 5, etc. You can divide by 2 as many times as possible before beginning. Then keep track of the largest odd number you have tried (prime or not, that will include all primes), so once they fail, you don't need to try them again.
New contributor
$endgroup$
add a comment |
$begingroup$
For starters, you only need to check odd numbers (potential primes) below sqrt(X).
If A*B=X, then either A=B and X is a perfect square, so the largest prime dividing A is the largest prime factor.
OR, one of A and B is less than the other, and thus less than the sqrt(X).
Without loss of generality, say A is less than B. Then B would be greater than the sqrt(X), but the largest prime factor in A or B would be the largest prime factor of X.
So, you can start testing B, and just like X, you only need to test numbers less than the sqrt(B), and when testing A those less than the sqrt(A).
You can keep a list of numbers that divide X, I would always try to find a factor of the largest number that divides X: If it is prime, it is the largest prime factor. But if you do find a factor of the largest, get rid of it and replace it with its two factors. Then once again, find the largest factor and prove it is prime or composite.
I would also start your loop for finding a factor "from the bottom", not from the top, to play the odds.
1/3 of all numbers are divisible by 3, 1/5 divisible by 5, etc. You can divide by 2 as many times as possible before beginning. Then keep track of the largest odd number you have tried (prime or not, that will include all primes), so once they fail, you don't need to try them again.
New contributor
$endgroup$
add a comment |
$begingroup$
For starters, you only need to check odd numbers (potential primes) below sqrt(X).
If A*B=X, then either A=B and X is a perfect square, so the largest prime dividing A is the largest prime factor.
OR, one of A and B is less than the other, and thus less than the sqrt(X).
Without loss of generality, say A is less than B. Then B would be greater than the sqrt(X), but the largest prime factor in A or B would be the largest prime factor of X.
So, you can start testing B, and just like X, you only need to test numbers less than the sqrt(B), and when testing A those less than the sqrt(A).
You can keep a list of numbers that divide X, I would always try to find a factor of the largest number that divides X: If it is prime, it is the largest prime factor. But if you do find a factor of the largest, get rid of it and replace it with its two factors. Then once again, find the largest factor and prove it is prime or composite.
I would also start your loop for finding a factor "from the bottom", not from the top, to play the odds.
1/3 of all numbers are divisible by 3, 1/5 divisible by 5, etc. You can divide by 2 as many times as possible before beginning. Then keep track of the largest odd number you have tried (prime or not, that will include all primes), so once they fail, you don't need to try them again.
New contributor
$endgroup$
For starters, you only need to check odd numbers (potential primes) below sqrt(X).
If A*B=X, then either A=B and X is a perfect square, so the largest prime dividing A is the largest prime factor.
OR, one of A and B is less than the other, and thus less than the sqrt(X).
Without loss of generality, say A is less than B. Then B would be greater than the sqrt(X), but the largest prime factor in A or B would be the largest prime factor of X.
So, you can start testing B, and just like X, you only need to test numbers less than the sqrt(B), and when testing A those less than the sqrt(A).
You can keep a list of numbers that divide X, I would always try to find a factor of the largest number that divides X: If it is prime, it is the largest prime factor. But if you do find a factor of the largest, get rid of it and replace it with its two factors. Then once again, find the largest factor and prove it is prime or composite.
I would also start your loop for finding a factor "from the bottom", not from the top, to play the odds.
1/3 of all numbers are divisible by 3, 1/5 divisible by 5, etc. You can divide by 2 as many times as possible before beginning. Then keep track of the largest odd number you have tried (prime or not, that will include all primes), so once they fail, you don't need to try them again.
New contributor
New contributor
answered Apr 25 at 15:57
AmadeusAmadeus
1311
1311
New contributor
New contributor
add a comment |
add a comment |
$begingroup$
The first problem is that you are trying to find all prime numbers under number. The number of prime numbers under x is approximately x/ln(x) which is around 22153972243.4 for our specific value of x
This is way too big ! So even if you where capable of obtaining each of these prime numbers in constant time it would take too much time.
This tells us this approach is most likely unfixable.
New contributor
$endgroup$
add a comment |
$begingroup$
The first problem is that you are trying to find all prime numbers under number. The number of prime numbers under x is approximately x/ln(x) which is around 22153972243.4 for our specific value of x
This is way too big ! So even if you where capable of obtaining each of these prime numbers in constant time it would take too much time.
This tells us this approach is most likely unfixable.
New contributor
$endgroup$
add a comment |
$begingroup$
The first problem is that you are trying to find all prime numbers under number. The number of prime numbers under x is approximately x/ln(x) which is around 22153972243.4 for our specific value of x
This is way too big ! So even if you where capable of obtaining each of these prime numbers in constant time it would take too much time.
This tells us this approach is most likely unfixable.
New contributor
$endgroup$
The first problem is that you are trying to find all prime numbers under number. The number of prime numbers under x is approximately x/ln(x) which is around 22153972243.4 for our specific value of x
This is way too big ! So even if you where capable of obtaining each of these prime numbers in constant time it would take too much time.
This tells us this approach is most likely unfixable.
New contributor
New contributor
answered Apr 25 at 4:48
Jorge FernándezJorge Fernández
30715
30715
New contributor
New contributor
add a comment |
add a comment |
$begingroup$
You already skip all even numbers.
For the same reason, create code that skips:
- every 3rd #
- every 5th #
- every 7th ... 11th ... 13th, maybe ...
New contributor
$endgroup$
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
add a comment |
$begingroup$
You already skip all even numbers.
For the same reason, create code that skips:
- every 3rd #
- every 5th #
- every 7th ... 11th ... 13th, maybe ...
New contributor
$endgroup$
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
add a comment |
$begingroup$
You already skip all even numbers.
For the same reason, create code that skips:
- every 3rd #
- every 5th #
- every 7th ... 11th ... 13th, maybe ...
New contributor
$endgroup$
You already skip all even numbers.
For the same reason, create code that skips:
- every 3rd #
- every 5th #
- every 7th ... 11th ... 13th, maybe ...
New contributor
edited Apr 25 at 15:00
AlexV
1,704520
1,704520
New contributor
answered Apr 25 at 14:28
yrlicyrlic
111
111
New contributor
New contributor
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
add a comment |
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
2
2
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
$begingroup$
That sort of stepping can get complicated quickly.
$endgroup$
– 1201ProgramAlarm
Apr 25 at 21:02
2
2
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
$begingroup$
@1201ProgramAlarm The best way would probably be to keep track of the previous primes and for each new prime, make sure it isn't a multiple of any previous prime. This is useful for generating the infinite sequence of primes (I think of it as an infinite sieve of Eratosthenes), but unless the number is big enough that taking it modulus a small number is too slow, it's best just to find the one modulus instead of finding many smaller ones.
$endgroup$
– Solomon Ucko
Apr 25 at 21:34
1
1
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
$begingroup$
@1201ProgramAlarm It is, however, how a basic sieve works. You assume all numbers are prime (an array of true) and mark of all multiples of two as composite, then all multiples of three, then all multiples of the next number that is still true.
$endgroup$
– Graipher
Apr 26 at 5:44
add a comment |
Eagle is a new contributor. Be nice, and check out our Code of Conduct.
Eagle is a new contributor. Be nice, and check out our Code of Conduct.
Eagle is a new contributor. Be nice, and check out our Code of Conduct.
Eagle is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219063%2fa-faster-way-to-compute-the-largest-prime-factor%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
6
$begingroup$
"
//to break the for loop
" Doesn't Javascript have abreak
?$endgroup$
– Arthur
Apr 25 at 12:16
$begingroup$
@Arthur yeah. I'm new to this, and forgot what exactly the word was. It was later pointed out in an answer (now deleted) here, after which I have updated my code. Thanks for pointing out though.
$endgroup$
– Eagle
2 days ago
1
$begingroup$
No worries. Knowing that any scope runs until the end is a known aesthetic goal when coding, and people who try to achieve that would probably also do something exactly like that. So I don't think it's that bad, really. And it's not like a single assignment rather than a break would tax the processor much, and a clever compiler might even optimise it away.
$endgroup$
– Arthur
2 days ago