How can I check for primality in Forth?
Here is what I use now, but it gets slow with higher numbers:
: prime ( n - f )
DUP 2 < IF
DROP 0 EXIT
THEN
DUP 2 ?DO
DUP I I * < IF
DROP -1 LEAVE
THEN
DUP I MOD 0= IF
DROP 0 LEAVE
THEN
LOOP ;
A simple probabilistic method is with the Fermat test, which you can look up in Wikipedia:
: *mod ( a b n -- n2 )
*/mod drop ;
: expmod { x e n -- n2 } \ compute x^e mod n by repeated squaring
e 0= if 1 exit
else
x e 2/ n recurse dup n *mod
e 1 and if x n *mod then
then ;
: prime ( n -- f )
3 swap dup expmod 3 = ;
If this test says the number is composite, then it is definitely composite. If it says the number is prime, then it is PROBABLY prime, but a few composite numbers will slip through (such numbers are called "pseudoprimes"). The test is quite fast and sufficient for some purposes.
The code you posted tests divisors 2,3,4,5,... up to the square root of n, and it would be about 2x as fast if it tested 2,3,5,7... since there's no need to test even divisors larger than 2.
Related
I want to have a code that calculates the Narayana numbers. https://en.wikipedia.org/wiki/Narayana_number
However, it starts to present '0' for numbers over 20.
What might be failing?
let rec factorial n =
if n <= 1 then 1
else factorial (n-1) * n;;
factorial 21 overflows and returns an incorrect result.
The max_int value of on my 64bit setup is 4611686018427387903, which is just between 20! and 21!.
The to get around this you can avoid actually calculating the value of n! (or k!) ub binomial_coeff. Instead calculate more complex values. For instance, instead of n!/k!, you can use (k+1)*(k+2)*...*n.
You missed a piece of code, that is factorial (n) as numerator:
let binomial_coeff (n:int) (k:int) =
if k = 0 || k = n then 1
else factorial (n) / (factorial (k) * factorial (n-k));;
I want to find the minimum set of prime numbers which would sum to a given value e.g. 9 = 7 + 2 (not 3+3+3).
I have already generated a array of prime numbers using sieve of eratosthens
I am traversing the array in descending order to get the array largest prime number smaller than or equal to given number. This works great if the number is odd.
But fails for even numbers e.g 122 = 113 + 7 + 2 but 122 = 109 +13.
From Golbach's Conjecture we know that any even number can be represented as two sum of two prime numbers. So if a number is even we can directly return 2 as output.
But I am trying to figure out a way other than brute force to find minimum prime numbers.
Although your question didn't say so, I assume you are looking for the set of primes that has the smallest cardinality.
If n is even, then consider the primes p in order, 2, 3, 5, …; eventually n - p will be prime, so n is the sum of two primes. This process typically converges very quickly, with the smaller of the two primes seldom larger than 1000 (and usually much smaller than that).
If n is odd, and n - 2 is prime, then n is the sum of the primes 2 and n - 2.
If n is odd, and n - 2 is not prime, then n - 3 is even and can be written as the sum of two primes, as described above.
Thus you can always find two or three primes that sum to any target n greater than 3.
Try this out!
Not an ideal code but if you want to have a working solution :P
primes = [2,3,5,7]
D = 29
i = -1
sum_ = 0
count = 0
while sum_ != D :
sum_ = sum_ + primes[i]
count += 1
if (sum_ == D) :
break
elif D - sum_ == primes[i-1] :
count += 1
break
elif D - sum_ < ex[i-1] and (D-sum_ not in primes) :
sum_ = sum_ - primes[i]
count = count - 1
i = i - 1
print(count)
I have to Convert positive integer number into its prime factorization form exponentially. For example:[(2,1), (5,1)] is the correct prime factorization of 10 as defined above.
I have this below code to generate factors.Now I should make them prime and should return their exponents also in tuples . Pl help me.
def primes(n):
divisors = [ d for d in range(2,n//2+1) if n % d == 0]
return divisors
You can directly follow the following approach which is O(n^(1/2)) in time complexity.
# n is the number to be factorized
# this list holds your desired answer
prime_factors = []
# this variable iterates over prime
start = 2
while start*start <= n:
if n % start == 0:
expo = 0
while n % start == 0:
expo = expo + 1
n = n / start
prime_factors.append([start,expo])
if n > 1:
prime_factors.append([n,1])
print prime_factors
This is a simple iterative method. Here is running version Prime Factorization. Click on right upper corner ( fork ) to run on your test case
n = 10. Can run on others also.
Consider a convergent serie in the form:
sum(((-1)^n)*something)
where n is the index of iteration (n goes from 1 to infinity).
If we implement direclty the formula, we have std::pow(-1, n) but is there a more "rapid" algorithmic trick to implement that ?
Check whether n is even or odd,
(n % 2 == 0) ? 1 : -1;
does it. If you want to avoid a branch,
1 - 2*(n & 1)
I'm assuming that sum(((-1)^n)*something) is pseudocode, and n is a variable bound by sum.
Let's extend that notation to sum(n <- [0,1,2,3..], ((-1)^n)*f(n)). Your best option would probably be to first split this into two sums, that you add together:
sum(n <- [0,2..], ((-1)^n)*f(n)) + sum(n <- [1,3..], ((-1)^n)*f(n))
In the first term, n is always even, so (-1)^n will always be +1. Analogously, in the second term, it will always be -1. We can now rewrite this as follows:
sum(n <- [0,2..], f(n)) + sum(n <- [1,3..], -f(n))
Since every term in the second sum is multiplied by a constant, we can move that constant out of the sum:
sum(n <- [0,2..], f(n)) - sum(n <- [1,3..], f(n))
Now, let's make sure these sums take the same sequences of indices, and substitute 2*m and 2*m+1 for n:
sum(m <- [0,1..], f(2*m)) - sum(m <- [0,1..], f(2*m+1))
Now we can unite these sums again:
sum(m <- [0,1..], f(2*m) - f(2*m+1))
Or, if you want pseudo-C:
T result = 0;
for(m = 0; m < limit; m+=2) {
result += f(m);
result -= f(m+1);
}
This saves you a multiplication by +1 or -1, as most seem to suggest here. Since your sequence is convergent, taking an extra term should not negatively influence the correctness of the answer.
Yeah, there is a magic trick: (-1)^n == 1 if and only if n is even, and (-1)^n == -1 if and only if n is odd. Thus:
int p = (n % 2 == 0) ? 1 : -1;
sum(p*something)
If you are doing this in a loop, you could simply do:
x = 1; // Assuming we start on n = 0
for(...) // or while(...)
{
sum += x * something;
x = -x;
}
This is most likely a lot faster than doing checks on n - of course, it DOES assume that all n values are iterated over, and you are not skipping a few here and there...
The term ((-1)^n)*something evaluates to -something for odd n, or something for even n:
n & 1 ? -something : something
If something is a constant value, then sum(((-1)^n)*something) evaluates to -something when the last value of n is odd, or 0 for an even number of summands:
n & 1 ? -something : 0
In this case, the serie would not be convergent.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?
I solved this problem on Project Euler my own way, which was slow, and then I found this solution on someone's github account. I can't figure out why it works. Why are a number of factors removed, equal to an index? Any insight?
def Euler3(n=600851475143):
for i in range(2,100000):
while n % i == 0:
n //= i
if n == 1 or n == i:
return i
This function works by finding successive factors of its input. The first factor it finds will necessarily be prime. After a prime factor is found, it is divided out of the original number and the process continues. By the time we've divided them all out (leaving 1, or the current factor (i)) we've got the last (largest) one.
Let's add some tracing code here:
def Euler3(n=600851475143):
for i in range(2,100000):
while n % i == 0:
n //= i
print("Yay, %d is a factor, now we should test %d" % (i, n))
if n == 1 or n == i:
return i
Euler3()
The output of this is:
$ python factor.py
Yay, 71 is a factor, now we should test 8462696833
Yay, 839 is a factor, now we should test 10086647
Yay, 1471 is a factor, now we should test 6857
Yay, 6857 is a factor, now we should test 1
It is true that for a general solution, the top of the range should have been the square root of n, but for python, calling math.sqrt returns a floating point number, so I think the original programmer was taking a lazy shortcut. The solution will not work in general, but it was good enough for the Euler project.
But the rest of the algorithm is sound.
Consider how it solves for n=20:
iteration i=2
while true (20 % 2 == 0)
n = n//2 = 20//2 = 10
if (n == 1 or n == 2) false
while true (10 % 2 == 0)
n = n//2 = 10//2 = 5
if (n == 1 or n == 2) false
while false (5 % 2 == 0)
iteration i = 3
while false (5 % 3 == 0)
iteration i = 4
while false (5 % 4 == 0)
iteration i = 5
while true (5 % 5 == 0)
n = n//5 = 5//5 = 1
if (n == 1 or n == 5) true
return i, which is 5, which is the largest prime factor of 20
It is just removing factors, and since it already removes multiples of prime factors (the while loop), many values of i are really just wasted effort. The only values of i that have any chance of doing something within the loop are prime values of i. The n==i test covers the case of numbers like 25 that are squares of a prime number.
The range seems to limited though. It would not give the correct answer for 2 * (the next largest prime after 100,000.
No one has actually answered your question. The for loop tests each number i in turn. The test of the while loop is successful when i is a factor of n; in that case, it reduces n, then checks if it is finished by comparing i to 1 or n. The test is a while (and not just if) in case i divides n more than once.
Though clever, that's not the way integer factorization by trial division is normally written; it also won't work if n has a factor greater than 100000. I have an explanation on my blog. Here's my version of the function, which lists all the factors of n instead of just the largest:
def factors(n):
fs = []
while n % 2 == 0:
fs += [2]
n /= 2
if n == 1:
return fs
f = 3
while f * f <= n:
if n % f == 0:
fs += [f]
n /= f
else:
f += 2
return fs + [n]
This function handles 2 separately, then tries only odd factors. It also doesn't place a limit on the factor, instead stopping when the factor is greater than the square root of the remaining n, because at that point n must be prime. The factors are inserted in increasing order, so the last factor in the output list will be the largest, which is the one you want.