nth Prime, and Prime Factors
Going through the Haskell tutorial, it said to write a function 'isPrime' to determine if a number is a prime number.
I came up with:
isPrime :: Integer -> Bool
isPrime n = factors n == [1,n]
where factors n = [x | x <- [1..n], n `mod` x == 0]
which works.
But how would I go about asking for the nth prime number -- as in, the 100th prime number is 541?
Playing around further with primes, I found a list of Prime Factors like this:
primeFactors :: Integer -> [Integer]
primeFactors n = filter prime (factors n)
where factors n = [x | x <- [1..n], n `mod` x == 0]
prime n = factors n == [1,n]
and that works, too.
However, when you put in a very large number, you get significant lag time.
As an example, it does these just fine:
ghci > primeFactors 419
[419]
ghci > primeFactors 5698
[2,7,11,37] -- did this one really fast...
ghci > primeFactors 76586
[2,149,257] -- and this one really fast...
ghci > primeFactors 876350
[2,5,17,1031] -- it hung up just a hair with this one...
ghci > primeFactors 4287635
[5,11,19,373] -- hung up a little bit longer here...
ghci > primeFactors 34598274
[2,3,5766379] -- hung up for quite a while here...
ghci > primeFactors 208346758
[2,104173379] -- and for a very long time with this one!
The tutorial suggested finding the prime factors of 62451532000, and on that one, I'm still waiting, after somewhere around 5 minutes.
What is causing the lag time, and what would be the best way to speed this up?
haskell
add a comment |
Going through the Haskell tutorial, it said to write a function 'isPrime' to determine if a number is a prime number.
I came up with:
isPrime :: Integer -> Bool
isPrime n = factors n == [1,n]
where factors n = [x | x <- [1..n], n `mod` x == 0]
which works.
But how would I go about asking for the nth prime number -- as in, the 100th prime number is 541?
Playing around further with primes, I found a list of Prime Factors like this:
primeFactors :: Integer -> [Integer]
primeFactors n = filter prime (factors n)
where factors n = [x | x <- [1..n], n `mod` x == 0]
prime n = factors n == [1,n]
and that works, too.
However, when you put in a very large number, you get significant lag time.
As an example, it does these just fine:
ghci > primeFactors 419
[419]
ghci > primeFactors 5698
[2,7,11,37] -- did this one really fast...
ghci > primeFactors 76586
[2,149,257] -- and this one really fast...
ghci > primeFactors 876350
[2,5,17,1031] -- it hung up just a hair with this one...
ghci > primeFactors 4287635
[5,11,19,373] -- hung up a little bit longer here...
ghci > primeFactors 34598274
[2,3,5766379] -- hung up for quite a while here...
ghci > primeFactors 208346758
[2,104173379] -- and for a very long time with this one!
The tutorial suggested finding the prime factors of 62451532000, and on that one, I'm still waiting, after somewhere around 5 minutes.
What is causing the lag time, and what would be the best way to speed this up?
haskell
It is enough to check up tosqrt n
. And userem
function rather thanmod
.rem
is faster.factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.
– Luis Morillo
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Considerfactor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also usefactor
function), so if n have m factors, it need nn * m
step, i.e. O(n * m). so why it is slow.
– assembly.jc
Nov 16 '18 at 12:07
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25
add a comment |
Going through the Haskell tutorial, it said to write a function 'isPrime' to determine if a number is a prime number.
I came up with:
isPrime :: Integer -> Bool
isPrime n = factors n == [1,n]
where factors n = [x | x <- [1..n], n `mod` x == 0]
which works.
But how would I go about asking for the nth prime number -- as in, the 100th prime number is 541?
Playing around further with primes, I found a list of Prime Factors like this:
primeFactors :: Integer -> [Integer]
primeFactors n = filter prime (factors n)
where factors n = [x | x <- [1..n], n `mod` x == 0]
prime n = factors n == [1,n]
and that works, too.
However, when you put in a very large number, you get significant lag time.
As an example, it does these just fine:
ghci > primeFactors 419
[419]
ghci > primeFactors 5698
[2,7,11,37] -- did this one really fast...
ghci > primeFactors 76586
[2,149,257] -- and this one really fast...
ghci > primeFactors 876350
[2,5,17,1031] -- it hung up just a hair with this one...
ghci > primeFactors 4287635
[5,11,19,373] -- hung up a little bit longer here...
ghci > primeFactors 34598274
[2,3,5766379] -- hung up for quite a while here...
ghci > primeFactors 208346758
[2,104173379] -- and for a very long time with this one!
The tutorial suggested finding the prime factors of 62451532000, and on that one, I'm still waiting, after somewhere around 5 minutes.
What is causing the lag time, and what would be the best way to speed this up?
haskell
Going through the Haskell tutorial, it said to write a function 'isPrime' to determine if a number is a prime number.
I came up with:
isPrime :: Integer -> Bool
isPrime n = factors n == [1,n]
where factors n = [x | x <- [1..n], n `mod` x == 0]
which works.
But how would I go about asking for the nth prime number -- as in, the 100th prime number is 541?
Playing around further with primes, I found a list of Prime Factors like this:
primeFactors :: Integer -> [Integer]
primeFactors n = filter prime (factors n)
where factors n = [x | x <- [1..n], n `mod` x == 0]
prime n = factors n == [1,n]
and that works, too.
However, when you put in a very large number, you get significant lag time.
As an example, it does these just fine:
ghci > primeFactors 419
[419]
ghci > primeFactors 5698
[2,7,11,37] -- did this one really fast...
ghci > primeFactors 76586
[2,149,257] -- and this one really fast...
ghci > primeFactors 876350
[2,5,17,1031] -- it hung up just a hair with this one...
ghci > primeFactors 4287635
[5,11,19,373] -- hung up a little bit longer here...
ghci > primeFactors 34598274
[2,3,5766379] -- hung up for quite a while here...
ghci > primeFactors 208346758
[2,104173379] -- and for a very long time with this one!
The tutorial suggested finding the prime factors of 62451532000, and on that one, I'm still waiting, after somewhere around 5 minutes.
What is causing the lag time, and what would be the best way to speed this up?
haskell
haskell
edited Nov 16 '18 at 11:54
jonrsharpe
78.8k11110221
78.8k11110221
asked Nov 16 '18 at 11:53
StormyStormy
673
673
It is enough to check up tosqrt n
. And userem
function rather thanmod
.rem
is faster.factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.
– Luis Morillo
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Considerfactor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also usefactor
function), so if n have m factors, it need nn * m
step, i.e. O(n * m). so why it is slow.
– assembly.jc
Nov 16 '18 at 12:07
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25
add a comment |
It is enough to check up tosqrt n
. And userem
function rather thanmod
.rem
is faster.factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.
– Luis Morillo
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Considerfactor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also usefactor
function), so if n have m factors, it need nn * m
step, i.e. O(n * m). so why it is slow.
– assembly.jc
Nov 16 '18 at 12:07
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25
It is enough to check up to
sqrt n
. And use rem
function rather than mod
. rem
is faster. factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.– Luis Morillo
Nov 16 '18 at 12:05
It is enough to check up to
sqrt n
. And use rem
function rather than mod
. rem
is faster. factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.– Luis Morillo
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Consider
factor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also use factor
function), so if n have m factors, it need n n * m
step, i.e. O(n * m). so why it is slow.– assembly.jc
Nov 16 '18 at 12:07
Consider
factor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also use factor
function), so if n have m factors, it need n n * m
step, i.e. O(n * m). so why it is slow.– assembly.jc
Nov 16 '18 at 12:07
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25
add a comment |
3 Answers
3
active
oldest
votes
The lag time is due to the factors function. It iterates from 1
to n
. So, if n
is 62451532000
, there will at least be 62451532000
steps. That's too many steps.
There are plenty of ways to speed this up. There's actually so many that one could write a book on it. I suggest you lookup factorization.
For now, try implementing this simple trick. Whenever d
is a factor of n
, so is n/d
. If you look for all factors below √n
, and utilize this trick, you would have found all the factors.
This would decrease the number of steps required from 62451532000
to about 250000
. Much more manageable.
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
add a comment |
You can easily get rid of prime
. A small change in your algorithm is enough for you to make sure than any new factor you find is guaranteed to be prime.
Here is how you do it. Every time you find an x
divides n
you remove all x
factors from n
and then proceed with that new value.
Consider the following example with number 40. Note that 40 = 2^3*5. So 40 is divisible by 1, 2, 4, 5, 8, 20 and 40. We begin testing for prime factors at 2.
40 `mod` 2 == 0
So 2 is a factor (and prime). So let's remove all the 2's
40 `mod` 2 == 0
40 `div` 2 == 20
20 `mod` 2 == 0
20 `div` 2 == 10
10 `mod` 2 == 0
10 `div` 2 == 5
5 `mod` 2 == 1
So we removed all the 2's from 40, until we got 5. Now we proceed with 5 instead. You check division by 3, then 4, then 5 which works. And note how 5 is indeed prime.
Now here is a question for you to think about. How does this method guarantee that each new factor you find is prime?
Note: Keep in mind however that while the method above should speed things up when dealing with big numbers composed of relatively small prime factors, it won't do much if you test it e.g. with a big prime number.
add a comment |
Yes, the consensus is the factor list [1..n]. It speeds things up when you minimize the factor list without losing effectiveness. I use a limited factor list that works. It assumes all primes are one-of-4 out of every 10, that is [11,13,17,19,21,23,27,29,31...]. The following starts at 11 (specified) because starting at 1 would include 1 and 9. All primes after 7 end in 1,3,7 or 9.
This list eliminates evens and 5s. The following eliminates 3s as well.
no2s3s5s = scanl (b a -> a + b) 11 $ cycle [2,4,2,4,6,2,6,4]
The length of the factor list need not exceed sqrt n
, so ...
fa n=[x|x<-2:3:5:7:(take (floor.sqrt.fromIntegral$n+2) no2s3s5s),mod n x == 0]
fa
lists factors, a lot of which are prime
fa 909090 OR fa 121
[2,3,5,7,13,37,91,259,481,3367] AND [11] recpectively
To remove the non-prime from the list
pr n = (null $ fa n) || (fa n == [n])
and
[ d | d<-2:3:5:7:(take 200 no2s3s5s), pr d ]
Produces a prime list but is slow as are all such functions that use a factor list or divisors such.
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: "1"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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
});
}
});
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%2fstackoverflow.com%2fquestions%2f53337362%2fnth-prime-and-prime-factors%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The lag time is due to the factors function. It iterates from 1
to n
. So, if n
is 62451532000
, there will at least be 62451532000
steps. That's too many steps.
There are plenty of ways to speed this up. There's actually so many that one could write a book on it. I suggest you lookup factorization.
For now, try implementing this simple trick. Whenever d
is a factor of n
, so is n/d
. If you look for all factors below √n
, and utilize this trick, you would have found all the factors.
This would decrease the number of steps required from 62451532000
to about 250000
. Much more manageable.
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
add a comment |
The lag time is due to the factors function. It iterates from 1
to n
. So, if n
is 62451532000
, there will at least be 62451532000
steps. That's too many steps.
There are plenty of ways to speed this up. There's actually so many that one could write a book on it. I suggest you lookup factorization.
For now, try implementing this simple trick. Whenever d
is a factor of n
, so is n/d
. If you look for all factors below √n
, and utilize this trick, you would have found all the factors.
This would decrease the number of steps required from 62451532000
to about 250000
. Much more manageable.
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
add a comment |
The lag time is due to the factors function. It iterates from 1
to n
. So, if n
is 62451532000
, there will at least be 62451532000
steps. That's too many steps.
There are plenty of ways to speed this up. There's actually so many that one could write a book on it. I suggest you lookup factorization.
For now, try implementing this simple trick. Whenever d
is a factor of n
, so is n/d
. If you look for all factors below √n
, and utilize this trick, you would have found all the factors.
This would decrease the number of steps required from 62451532000
to about 250000
. Much more manageable.
The lag time is due to the factors function. It iterates from 1
to n
. So, if n
is 62451532000
, there will at least be 62451532000
steps. That's too many steps.
There are plenty of ways to speed this up. There's actually so many that one could write a book on it. I suggest you lookup factorization.
For now, try implementing this simple trick. Whenever d
is a factor of n
, so is n/d
. If you look for all factors below √n
, and utilize this trick, you would have found all the factors.
This would decrease the number of steps required from 62451532000
to about 250000
. Much more manageable.
answered Nov 16 '18 at 12:11
merlynmerlyn
1,77011323
1,77011323
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
add a comment |
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
combined with the other answer's approach, there'd be about 75 steps, for 62451532000.
– Will Ness
Nov 16 '18 at 15:56
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
if you change the logic and decide with the first non-trivial factor, it should only take 1 step, namely when testing for factor 2.
– karakfa
Nov 16 '18 at 17:26
add a comment |
You can easily get rid of prime
. A small change in your algorithm is enough for you to make sure than any new factor you find is guaranteed to be prime.
Here is how you do it. Every time you find an x
divides n
you remove all x
factors from n
and then proceed with that new value.
Consider the following example with number 40. Note that 40 = 2^3*5. So 40 is divisible by 1, 2, 4, 5, 8, 20 and 40. We begin testing for prime factors at 2.
40 `mod` 2 == 0
So 2 is a factor (and prime). So let's remove all the 2's
40 `mod` 2 == 0
40 `div` 2 == 20
20 `mod` 2 == 0
20 `div` 2 == 10
10 `mod` 2 == 0
10 `div` 2 == 5
5 `mod` 2 == 1
So we removed all the 2's from 40, until we got 5. Now we proceed with 5 instead. You check division by 3, then 4, then 5 which works. And note how 5 is indeed prime.
Now here is a question for you to think about. How does this method guarantee that each new factor you find is prime?
Note: Keep in mind however that while the method above should speed things up when dealing with big numbers composed of relatively small prime factors, it won't do much if you test it e.g. with a big prime number.
add a comment |
You can easily get rid of prime
. A small change in your algorithm is enough for you to make sure than any new factor you find is guaranteed to be prime.
Here is how you do it. Every time you find an x
divides n
you remove all x
factors from n
and then proceed with that new value.
Consider the following example with number 40. Note that 40 = 2^3*5. So 40 is divisible by 1, 2, 4, 5, 8, 20 and 40. We begin testing for prime factors at 2.
40 `mod` 2 == 0
So 2 is a factor (and prime). So let's remove all the 2's
40 `mod` 2 == 0
40 `div` 2 == 20
20 `mod` 2 == 0
20 `div` 2 == 10
10 `mod` 2 == 0
10 `div` 2 == 5
5 `mod` 2 == 1
So we removed all the 2's from 40, until we got 5. Now we proceed with 5 instead. You check division by 3, then 4, then 5 which works. And note how 5 is indeed prime.
Now here is a question for you to think about. How does this method guarantee that each new factor you find is prime?
Note: Keep in mind however that while the method above should speed things up when dealing with big numbers composed of relatively small prime factors, it won't do much if you test it e.g. with a big prime number.
add a comment |
You can easily get rid of prime
. A small change in your algorithm is enough for you to make sure than any new factor you find is guaranteed to be prime.
Here is how you do it. Every time you find an x
divides n
you remove all x
factors from n
and then proceed with that new value.
Consider the following example with number 40. Note that 40 = 2^3*5. So 40 is divisible by 1, 2, 4, 5, 8, 20 and 40. We begin testing for prime factors at 2.
40 `mod` 2 == 0
So 2 is a factor (and prime). So let's remove all the 2's
40 `mod` 2 == 0
40 `div` 2 == 20
20 `mod` 2 == 0
20 `div` 2 == 10
10 `mod` 2 == 0
10 `div` 2 == 5
5 `mod` 2 == 1
So we removed all the 2's from 40, until we got 5. Now we proceed with 5 instead. You check division by 3, then 4, then 5 which works. And note how 5 is indeed prime.
Now here is a question for you to think about. How does this method guarantee that each new factor you find is prime?
Note: Keep in mind however that while the method above should speed things up when dealing with big numbers composed of relatively small prime factors, it won't do much if you test it e.g. with a big prime number.
You can easily get rid of prime
. A small change in your algorithm is enough for you to make sure than any new factor you find is guaranteed to be prime.
Here is how you do it. Every time you find an x
divides n
you remove all x
factors from n
and then proceed with that new value.
Consider the following example with number 40. Note that 40 = 2^3*5. So 40 is divisible by 1, 2, 4, 5, 8, 20 and 40. We begin testing for prime factors at 2.
40 `mod` 2 == 0
So 2 is a factor (and prime). So let's remove all the 2's
40 `mod` 2 == 0
40 `div` 2 == 20
20 `mod` 2 == 0
20 `div` 2 == 10
10 `mod` 2 == 0
10 `div` 2 == 5
5 `mod` 2 == 1
So we removed all the 2's from 40, until we got 5. Now we proceed with 5 instead. You check division by 3, then 4, then 5 which works. And note how 5 is indeed prime.
Now here is a question for you to think about. How does this method guarantee that each new factor you find is prime?
Note: Keep in mind however that while the method above should speed things up when dealing with big numbers composed of relatively small prime factors, it won't do much if you test it e.g. with a big prime number.
edited Nov 16 '18 at 13:31
answered Nov 16 '18 at 12:55
Jorge AdrianoJorge Adriano
2,219919
2,219919
add a comment |
add a comment |
Yes, the consensus is the factor list [1..n]. It speeds things up when you minimize the factor list without losing effectiveness. I use a limited factor list that works. It assumes all primes are one-of-4 out of every 10, that is [11,13,17,19,21,23,27,29,31...]. The following starts at 11 (specified) because starting at 1 would include 1 and 9. All primes after 7 end in 1,3,7 or 9.
This list eliminates evens and 5s. The following eliminates 3s as well.
no2s3s5s = scanl (b a -> a + b) 11 $ cycle [2,4,2,4,6,2,6,4]
The length of the factor list need not exceed sqrt n
, so ...
fa n=[x|x<-2:3:5:7:(take (floor.sqrt.fromIntegral$n+2) no2s3s5s),mod n x == 0]
fa
lists factors, a lot of which are prime
fa 909090 OR fa 121
[2,3,5,7,13,37,91,259,481,3367] AND [11] recpectively
To remove the non-prime from the list
pr n = (null $ fa n) || (fa n == [n])
and
[ d | d<-2:3:5:7:(take 200 no2s3s5s), pr d ]
Produces a prime list but is slow as are all such functions that use a factor list or divisors such.
add a comment |
Yes, the consensus is the factor list [1..n]. It speeds things up when you minimize the factor list without losing effectiveness. I use a limited factor list that works. It assumes all primes are one-of-4 out of every 10, that is [11,13,17,19,21,23,27,29,31...]. The following starts at 11 (specified) because starting at 1 would include 1 and 9. All primes after 7 end in 1,3,7 or 9.
This list eliminates evens and 5s. The following eliminates 3s as well.
no2s3s5s = scanl (b a -> a + b) 11 $ cycle [2,4,2,4,6,2,6,4]
The length of the factor list need not exceed sqrt n
, so ...
fa n=[x|x<-2:3:5:7:(take (floor.sqrt.fromIntegral$n+2) no2s3s5s),mod n x == 0]
fa
lists factors, a lot of which are prime
fa 909090 OR fa 121
[2,3,5,7,13,37,91,259,481,3367] AND [11] recpectively
To remove the non-prime from the list
pr n = (null $ fa n) || (fa n == [n])
and
[ d | d<-2:3:5:7:(take 200 no2s3s5s), pr d ]
Produces a prime list but is slow as are all such functions that use a factor list or divisors such.
add a comment |
Yes, the consensus is the factor list [1..n]. It speeds things up when you minimize the factor list without losing effectiveness. I use a limited factor list that works. It assumes all primes are one-of-4 out of every 10, that is [11,13,17,19,21,23,27,29,31...]. The following starts at 11 (specified) because starting at 1 would include 1 and 9. All primes after 7 end in 1,3,7 or 9.
This list eliminates evens and 5s. The following eliminates 3s as well.
no2s3s5s = scanl (b a -> a + b) 11 $ cycle [2,4,2,4,6,2,6,4]
The length of the factor list need not exceed sqrt n
, so ...
fa n=[x|x<-2:3:5:7:(take (floor.sqrt.fromIntegral$n+2) no2s3s5s),mod n x == 0]
fa
lists factors, a lot of which are prime
fa 909090 OR fa 121
[2,3,5,7,13,37,91,259,481,3367] AND [11] recpectively
To remove the non-prime from the list
pr n = (null $ fa n) || (fa n == [n])
and
[ d | d<-2:3:5:7:(take 200 no2s3s5s), pr d ]
Produces a prime list but is slow as are all such functions that use a factor list or divisors such.
Yes, the consensus is the factor list [1..n]. It speeds things up when you minimize the factor list without losing effectiveness. I use a limited factor list that works. It assumes all primes are one-of-4 out of every 10, that is [11,13,17,19,21,23,27,29,31...]. The following starts at 11 (specified) because starting at 1 would include 1 and 9. All primes after 7 end in 1,3,7 or 9.
This list eliminates evens and 5s. The following eliminates 3s as well.
no2s3s5s = scanl (b a -> a + b) 11 $ cycle [2,4,2,4,6,2,6,4]
The length of the factor list need not exceed sqrt n
, so ...
fa n=[x|x<-2:3:5:7:(take (floor.sqrt.fromIntegral$n+2) no2s3s5s),mod n x == 0]
fa
lists factors, a lot of which are prime
fa 909090 OR fa 121
[2,3,5,7,13,37,91,259,481,3367] AND [11] recpectively
To remove the non-prime from the list
pr n = (null $ fa n) || (fa n == [n])
and
[ d | d<-2:3:5:7:(take 200 no2s3s5s), pr d ]
Produces a prime list but is slow as are all such functions that use a factor list or divisors such.
edited Nov 17 '18 at 20:26
answered Nov 16 '18 at 23:18
fp_morafp_mora
43346
43346
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- 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.
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%2fstackoverflow.com%2fquestions%2f53337362%2fnth-prime-and-prime-factors%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
It is enough to check up to
sqrt n
. And userem
function rather thanmod
.rem
is faster.factors n = [x | x <- [1.. sqrt n], n `rem` x == 0]
. Check if the list is has more than one elem.– Luis Morillo
Nov 16 '18 at 12:05
Checking all possible factors is rather useless. You are interested in prime factors. If a number has no prime factors (smaller than itself), it has no other interesting factors.
– n.m.
Nov 16 '18 at 12:05
Consider
factor n
, you need to check each number < n whether is factor of n, so it take n steps, and each factor of n need to check whether is prime (also usefactor
function), so if n have m factors, it need nn * m
step, i.e. O(n * m). so why it is slow.– assembly.jc
Nov 16 '18 at 12:07
you don't need to compute all factors, if you find a non-trivial factor before sqrt(n) just exit early. This should speed up dramatically for numbers small factors (e.g. 62451532000).
– karakfa
Nov 16 '18 at 17:25