Find minimum prime numbers which sum to a given value - primes

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)

Related

Product of three primes divisible by sum of those primes

I found this problem in a cp contest which is over now so it can be answered.
Three primes (p1,p2,p3) (not necessarily distinct) are called special if (p1+p2+p3) divides p1*p2*p3. We have to find the number of these special pairs if the primes can't exceed 10^6
I tried brute force method but it timed out. Can there be any other method?
If you are timing out, then you need to do some smart searching to replace brute force. There are just short of 80,000 primes below a million so it is not surprising you timed out.
So, you need to start looking more carefully.
For example, any triple (2, p, p+2) where p+2 is also prime will meet the criteria:
2 + 3 + 5 = 10; 2 * 3 * 5 = 30; 30 / 10 = 3.
2 + 5 + 7 = 14; 2 * 5 * 7 = 70. 70 / 14 = 5.
...
2 + p + p+2 = 2(p+2); 2 * p * (p+2) = 2p(p+2); 2p(p+2) / 2(p+2) = p.
...
Are there other triples that start with 2? Are there triples that start with 3? What forms do p2 and p3 take if p1= 3? Run your program for triples up to 500 or so and look for patterns in the results. Then extrapolate those results to 10^6.
I assume you are using a Sieve to generate your initial list of primes.
I've experimented with this problem since you posted it. I've not solved it, but wanted to pass along what insight I have before I move onto something else:
Generating Primes is Not the Issue
With a proper sieve algorithm, we can generate all primes under 10**6 in a fraction of a second. (Less than 1/3 of a second on my Mac mini.) Spending time optimizing prime generation beyond this is time wasted.
The Brute Force Method
If we try to generate all permutations of three primes in Python, e.g.:
for prime_1 in primes:
for prime_2 in primes:
if prime_2 < prime_1:
continue
for prime_3 in primes:
if prime_3 < prime_2:
continue
pass
Or better yet, push the problem down to the C level via Python's itertools:
from itertools import combinations_with_replacement
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
pass
Then, our timings, doing no actual work except generating prime triples, looks like:
sec.
10**2 0.04
10**3 0.13
10**4 37.37
10**5 ?
You can see how much time increases with each order of magnitude. Here's my example of a brute force solution:
from itertools import combinations_with_replacement
def sieve_primes(n): # assumes n > 1
sieve = [False, False, True] + [True, False] * ((n - 1) // 2)
p = 3
while p * p <= n:
if sieve[p]:
for i in range(p * p, n + 1, p):
sieve[i] = False
p += 2
return [number for number, isPrime in enumerate(sieve) if isPrime]
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
if (prime_1 * prime_2 * prime_3) % (prime_1 + prime_2 + prime_3) == 0:
special += 1
print(special)
Avoid Generating Triples, but Still Brute Force
Here's an approach that avoids generating triples. We take the smallest and largest primes we generated, cube them, and loop over them with a custom factoring function. This custom factoring function only returns a value for those numbers that are made up of exactly three prime factors. For any number made up of more or less, it returns None. This should be faster than normal factoring as the function can give up early.
Numbers that factor into exactly three primes are easy to test for specialness. We're going to pretend our custom factoring function takes no time at all and simply measure how long it takes us to loop over all the numbers in question:
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
pass
Again, some timings:
sec.
10**2 0.14
10**3 122.39
10**4 ?
Doesn't look promising. In fact, worse than our original brute force method. And our custom factoring function in reality adds a lot of time. Here's my example of this solution (copy sieve_primes() from the previous example):
def factor_number(n, count):
size = 0
factors = []
for prime in primes:
while size < count and n % prime == 0:
factors.append(prime)
n //= prime
size += 1
if n == 1 or size == count:
break
if n > 1 or size < count:
return None
return factors
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
factors = factor_number(number, 3)
if factors:
if number % sum(factors) == 0:
special += 1
print(special)

Euler project Prob 23 Non abundant sums :python2

I am trying to solve problem 23 in project euler in python2. I am getting the result as 4179935 but the correct answer is 4179871
This is the actual question
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example,
the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of
two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be
written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis
even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
import itertools
def find_non_abundant_sums(num):
non_abundant_number = set()
non_abundant_sums = set()
all_numbers = set(range(1,num+1))
for i in range(1,num+1):
divisor_sum = find_divisor_sum(i)
if(divisor_sum > i):
non_abundant_number.add(i)
for j in itertools.combinations(non_abundant_number,2):
if(j[0]+j[1] < num+1):
non_abundant_sums.add(j[0]+j[1])
print (sorted(non_abundant_sums))
return sum(all_numbers-non_abundant_sums)
def find_divisor_sum(num):
divisors = set()
for i in range(1,num):
if(num%i==0):
divisors.add(i)
return sum(divisors)
print (find_non_abundant_sums(28123))
expected: 4179871
actual: 4179935

finding the digit sum in a arthematic sequence

I have a very simple question. I will be provided with the first term of Arithmetic Progression and the common difference. I am required to give sum of digits of all numbers in between the range of L and R.Here the sum means the sum <10 that means for a number say 157, the sum of digits is 1+5+7=13 which is further 1+3=4. The range is the index of the elements. L means the Lth number of that series and L starts from 1.Here L and R can be of range 1 to 10^18. How can i find the sum of these digits for such a large range. I know the digit sum of a number n can be calculated as (n-1)%9+1. But i can't iterate over 10^18 numbers.
Example: let say First term of Arithmetic Progression is 14 and common difference 7.Then the sum of digits of all numbers between 2 and 4 will be sum of (2+1)=3 and (2+8)=(1+0)=1 and (3+5)=8 which is equal to 12
for pattern finding
current=first;
ll arr[10]={0};
while(1)// search for the pattern
{
ll dsum=(current-1)%9+1;// calculating digit sum
if(arr[dsum]!=0)
break;
arr[dsum]=ptr;// saving the value in the array by using hashing
ptr++;
current+=c_diff;
}
for sum
for(ll i=1;i<ptr;i++)
{
sum[i]=sum[i-1]+new_arr[i];
}
Since all of your numbers will be (ultimately) reduced to a single digit, you must be having repetition after certain number of terms, and, that is maximum of 9. (because 10 digits, but 0 not possible to repeat).
So, lets start with an example. Say, a=14, d=7, l=2, r=50. I've changed the value of r from your example.
So, trying to find repetition:
Our repetition array is q (say). Then, 1st term of q is 5 (since 14 = 5).
Now, next term is 21 (= 3). Since 3 is not equal to 5, we continue.
We find all terms till we get 5 again. So, q will be like this in this example:
q[] = {5,3,1,8,6,4,2,9,7} ... and then we have 5 again, so stop.
So, our repetitive pattern has 9 members. Now, find a cumulative sum array with this, which will be like:
sum[] = {5,8,9,17,23,27,29,38,45}
Now, since r=50, find sum of r terms, which will be:
(floor)(50/9) * 45 + sum[50%9]
= 5 * 45 + 23
= 248
Now, similarly, find sum of l-1 terms, (since you have to find sum in range l..r inclusive.
Sum of 1st (2-1) = 1 terms will be:
(floor)(1/9) * 45 + sum[1 % 9]
= 0 + 5
= 5
So, the answer is, 248 - 5 = 243.
well you can solve this problem by taking two arrays of elements 9 and finding the lth term element.
from the lth term find the digit sum of lth element and save it in two array respectively .
w1=a+(l-1)*d
for(i=1,j=w1;i<=9;j+=d,i++){ if(j%9==0){array1[i]=9 ;array2[i]=9;}else{array1[i]=j%9;array2[i]=j%9;}
}
now q = r-l+1
w= q/9 and e=q%9
array1[i]=array1[i]*w // in loop from i= 1 to 9
in array2[i]=0 //new loop from i=e+1 to 9
now digitsum += array1[i]+array2[i] // from a a loop i=1 to 9 and digitsum is the sum of all digit of sequence
this digit sum is solution.

How to count co-prime to n in a range [1,x] where x can be different from n?

I want to count co-primes of n in a range [1,x]. I have tried using euler phi function but it gives for [1,n].Can anyone suggest a modification to euler phi or any other approach to do this?
I have used phi(n) = n* product of (1-(1/p)) where p is a prime factor of n.
You can use Inclusion-Exclusion Principle
Find the unique prime factors of N (they cannot be more than 10-12, Considering N and X <=10^10).
Now you can find the number of numbers <=x and divisible by 'y' just by dividing. Try all combination of factors of n for y (you will get only 2^10 (1024) in worst case).
Use Inclusion Exclusion now to find the co-primes of n less than x.
The idea is that if a number is not co-prime to n, then it will have
at least one prime factor common with n.
For our example here lets consider X=35 and N=30
First find the unique prime factor of the number. (their number must not be greater than 10-12). Unique Prime factor of N ={2,3,5}.
Find the product of each factor PAIR. {2x3, 2x5, 3x5 or 6, 10, 15}.
Find the product of each factor TRIPLET: { 2x3x5 or 30}.
Repeat until all factors are multiplied together: {N=30 and no more steps are required}.
Find the sum of X divided by each factor from STEP 1: {X=35: (35/2)+(35/3)+(35/5) = (17+11+7)=35}
Find the sum of X divided by each number from STEP 2: {X=35: 35/65+3+2=10}
Find the sum of X divided by each number from STEP 3: {X=35: 1}
Repeat until all results from step 4 are absorbed: {x=35 no more steps are required}
Number of co-primes to N in the range [1..X] = X - step5 + step6 - step7 etc. {N=30, X=35 is given by 35 - 35 + 10 - 1 = 9}.
For N=30, X=60 you will have:
60 - (60/2 + 60/3 + 60/5) + (60/6 + 60/10+ 60/15) - (60/30) = 60 -
(30+20+12) + (10+6+4) - 2 = 60 -62 + 20 - 2 = 16.
Suppose X = 10. N = 6 = 2 * 3.
We have the numbers {1, 2, 3, ..., 10}.
Remove all multiples of 2. You get: {1, 3, 5, 7, 9}.
Remove all multiples of 3. You get: {1, 5, 7}.
How do we count this efficiently? Try answering this question: How many numbers are there in [1, X] that are divisible by p? It's Floor(X/p), right? i.e., p, 2p, ..., kp, where kp <= X. So, from X, we can subtract Floor(X/p),
and you will get the number of numbers that are relatively prime to p in [1, X].
In this example, there are 10 numbers. Number of numbers divisible by 2 is 10/2, which is 5. So, 10-5 = 5 numbers are relatively prime to 2. Similary, there are 10/3=3 numbers which are multiples of 3. So, can we say that there are 5-3=2 numbers that are relatively prime to 2 and 3? No. Because you have double counted! Why? 6 has been included in the count for p = 2 and 3. So we have to account for this by adding multiples of 2 and 3. There is only one multiple of 2 and 3 in [1, 10], which is 6. So, add 1. Which means, the answer is 10 - 5 - 3 + 1 = 3, which is right.
The generalisation of this is the inclusion and exclusion principle. For every n, we are just finding its prime factors, which I know for sure will be less than 10 or so. This is done using the Sieve of Eratosthenes, followed by a prime factorisation. (since X < 10^9, the maximum number of prime factors a number will have is less. Try finding out the product of the first 10 primes. It will be: 6469693230, which is about ~ 64*10^9.(i consider max limit as 10^10. this can be easily extended to big numbers like 10^18.)
i hope this helps !!

Project Euler 3 - Why does this method work?

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.