I am solving the 50th problem on Project Euler.
The question is to:
Find the prime number below one-million, which can be written as the sum of the most consecutive primes.
For example, 41 = 2 + 3 + 5 + 7 + 11 + 13
41 is the prime number that can be written as the sum of the most consecutive primes.
I wrote a code to find the prime numbers below 1000 that can be written as the sum of the most consecutive primes, to check if my code finds the prime number(953) which can be written as the sum of the most consecutive primes below 1000. This is what I came up with:
#!/usr/bin/python
import prime
p = prime.genprimes(1000)
prms = [i for i in p]
for prm in prms:
count = 0
p = prm
temp = []
for a in prms:
p -= a
temp.append(a)
count += 1
if p == 0:
print prm, '\t', count, '\t', temp
prime.py:
#!/usr/bin/python
def genprimes(limit):
"""
Returns the prime numbers(generator) until the limit(inclusive) given.
"""
D = {}
q = 2
while q <= limit:
if q not in D:
yield q
D[q * 2] = [q]
else:
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
Output when I run the code:
2 1 [2]
5 2 [2, 3]
17 4 [2, 3, 5, 7]
41 6 [2, 3, 5, 7, 11, 13] # Longest sum of consecutive primes that adds to a prime below 100
197 12 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
281 14 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]
The problem is it doesn't find the prime number 953 which is the longest sum of consecutice primes that adds to a prime below 1000.
So, I changed my code to troubleshoot what it does when prm is 953 in the for loop:
#!/usr/bin/python
import prime
p = prime.genprimes(1000)
prms = [i for i in p]
found = []
for prm in prms:
if prm == 953:
p = prm
for a in prms:
print p, '\t', a
p -= a
if p < -100:
break
Output:
953 2
951 3
948 5
943 7
936 11
925 13
912 17
895 19
876 23
853 29
824 31
793 37
756 41
715 43
672 47
625 53
572 59
513 61
452 67
385 71
314 73
241 79
162 83
79 89
-10 97
Any idea what I am doing wrong here? Thanks for any help.
Your loop always starts with the index 2. The consecutive primes it seems don't necessarily need to start with the prime 2. You will need to vary which prime the consecutive adding starts at.
A smaller example: if you were finding the largest sum of consecutive primes with sum less than 10, then that is 3 + 5 = 8, not 2 + 3 = 5.
It might not (and is not) the case that you always get the largest sum by adding all the primes starting at 2.
This Question was asked in TCS CodeVita 2016
#include<iostream>
using namespace std;
int main(){
long long int num=0;
cout<<"Enter the Size to count Prime number till NUM : ";
cin>>num;
long long int ary[num],j=2;
ary[0] =2,ary[1]=3;
for(int i=2;i<=num;i++){ // loop will add the prime number till num
if(i%2 != 0 && i%3 != 0){
ary[j] = i;
j++;
}
}
long long int k,sum=0,count=0;
cout<<"Sum of Consecutive Prime numbers from "<<2<<" to "<<num<<endl;
for(int i=0;i<=j;i++){
for(k=0;k<j;k++){
sum+= ary[k];
if(sum %2 !=0 && sum%3!=0 && sum<=num){
count++;
cout<<sum<<endl;
}
}
}
cout<<"Total Consecutive Count : "<<count<<endl;
}
OUTPUT
Sample Output 1
Enter the Size to count Prime number till NUM : 20
Sum of Consecutive Prime numbers from 2 to 20
5
17
Total Consecutive Count : 2
Sample Output 2
Enter the Size to count Prime number till NUM : 100
Sum of Consecutive Prime numbers from 2 to 100
5
17
41
77
Total Consecutive Count : 4
Related
Here's the definition of Modest Number.
A number n is called modest if its digits can be separated into two numbers a and b such that n divided by b gives a as remainder.
For example, 2851111 is modest because divided by 1111 gives 285 as remainder.
Here's an example which I considered:
is_modest(21333) ➞ True
Combination 1: Left = 2 | Right = 1333 21333 % 1333 = 5 != Left
Combination 2: Left = 21 | Right = 333 21333 % 333 = 21 = Left
At least a combination satisfies the condition
Below is what I tried:
def isModest(num):
numStr = str(num)
numLen = len(numStr)
while numLen > 1:
for i in range(1, numLen):
rem = num % (int(numStr[i:])) # 5, 21, 15, 0
if rem == int(numStr[:i]):
return True
else:
return False
print(isModest(2036)) <br>
print(isModest(3412)) <br>
print(isModest(21333)) <br>
print(isModest(8)) #??? <br>
You don't need to use string manipulations. Dividing by powers of 10 will do it more efficiently
def isModest(N):
if N<10: return "cannot split"
p10 = 10
while p10 < N:
a,b = divmod(N,p10)
if b and N%b == a: return True
p10 *= 10
return False
for n in range(1,100):
if isModest(n) is True: print(n)
13
19
23
26
29
39
46
49
59
69
79
89
I've recently started learning Python. I was doing some exercises on the Control Structures section of the course and everything was going fine until I got stumped on the last problem. I've been looking at it for three days now, and I'm pretty sure that the solution is quite obvious. Here is a description in the exercise:
Start with any number. If the number is divisible by 3, divide it by
3. Otherwise, add 2 to the number. Eventually, no matter what number you begin with, this series will run into 1. For example, imagine we
started with the number 5: 5 is not divisible by 3, so 5 + 2 = 7 7 is
not divisible by 3, so 7 + 2 = 9 9 is divisible by 3, so 9 / 3 = 3 3
is divisible by 3, so 3 / 3 = 1
Start with 5, this sequence converges on 1 in 4 iterations: 5 -> 7, 7
-> 9, 9 -> 3, 3 -> 1.
Write a function called joyner. joyner should have one parameter, an
integer. It should return the number of iterations required to reach 1
for the first time.
I ran the function I wrote on a page that tests my function with different integers. Every time it gave me an error (saying how many iterations were expected and how many my program calculated) I managed to fix the program for that integer, but the following integer tested would give me an error again. The code is below is the final re-write before I decided to come here to ask for help.
def joyner(num):
count = 0
while num % 3 != 0:
# print("num not divisible by 3")
num = num + 2
# print("added 2")
count += 1
# print(count)
if num % 3 == 0:
# print("num is divisible by 3")
num /= 3
# print("divided by 3")
count += 1
# print(count)
while num % 3 == 0:
# print("num is divisible by 3")
num /= 3
# print("divided by 3")
count += 1
# print(count)
return count
Here are the results:
We found the following problems with your submission:
We tested your code with num = 15. We expected joyner to return the
int 5. However, it returned the int 1.
We tested your code with num = 29. We expected joyner to return the
int 10. However, it returned the int 3.
We tested your code with num = 65. We expected joyner to return the
int 8. However, it returned the int 3.
We tested your code with num = 12. We expected joyner to return the
int 3. However, it returned the int 1.
We tested your code with num = 32. We expected joyner to return the
int 6. However, it returned the int 4.
Note that these errors may have prevented us from checking your
submission in other ways, so fixing these problems may cause other
problems to show up next time. Keep trying! This is what debugging is
all about.
The following things were correct about your submission:
We expected to find a function named joyner in your code, and we did.
We tested your code with num = 5. We expected joyner to return the int
4, and it did.
We tested your code with num = 27. We expected joyner to return the
int 3, and it did.
We tested your code with num = 16. We expected joyner to return the
int 3, and it did.
The thing with your code is that it assumes that when a number is no longer divisible by 3 that it reached 1, that is regarding your second loop, for example 15 is divisible by 3, it becomes 5, which is not divisible but also not 1.
Overall think about it this way, a number may be either divisible or not at once, so it should happen in one loop, and you should stop when you reach 1.
The premise of your task is not correct:
Start with any number. If the number is divisible by 3, divide it by 3. Otherwise, add 2 to the number. Eventually, no matter what number you begin with, this series will run into 1.
number = 4
4 + 2 = 6 # 4 is not divisible by 3, add 2
6 / 3 = 2 # 6 is divisible by 3 -> 2
2 + 2 = 4 # 2 is not divisible by 3, add 2
4 + 2 = 6 # 4 is not divisible by 3, add 2 --> cycle - no solution.
If there is a solution, this finds it:
def joyner(num):
count = 0
seen = set()
while num != 1:
if num in seen:
return None
else:
seen.add(num)
if num % 3 == 0:
num = num // 3
else:
num += 2
count += 1
return count
Test it:
i = 0
for k,c in d.items():
if c is None:
continue
print(k,":",c, end=" ")
i += 1
if i % 6 == 0:
print()
i = 0
Output of solutions from 1 to 99:
1 : 0 3 : 1 5 : 4 7 : 3 9 : 2 11 : 7
13 : 6 15 : 5 17 : 6 19 : 5 21 : 4 23 : 5
25 : 4 27 : 3 29 : 10 31 : 9 33 : 8 35 : 9
37 : 8 39 : 7 41 : 8 43 : 7 45 : 6 47 : 9
49 : 8 51 : 7 53 : 8 55 : 7 57 : 6 59 : 7
61 : 6 63 : 5 65 : 8 67 : 7 69 : 6 71 : 7
73 : 6 75 : 5 77 : 6 79 : 5 81 : 4 83 : 13
85 : 12 87 : 11 89 : 12 91 : 11 93 : 10 95 : 11
97 : 10 99 : 9
Not viable:
[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40,
42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78,
80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
Your algo only works for odd numbers.
We tested your code with num = 12. We expected joyner to return the int 3. However, it returned the int 1.
does not work at all
Write a program to compute the sum of the terms of the series: 4 - 8 + 12 - 16 + 20 -
24 + 28 - 32 + .... +/- n, where n is an input. Consider that n is always valid (which
means it follows the series pattern).
n = int(input("Enter n: "))
sum = 0
for i in range(4,n+4,4):
sum += i - (i+2)
print("The sum of %s first terms is: %s"%(n,sum))
Can't seem to find the issues that Ihave
How about an explicit formula?
def sumSeries(n):
if n / 4 % 2 == 0:
return - n / 2
else:
return (n + 4) / 2
The series doesn't do anything too interesting, it just keeps adding +4 every two steps, and flips the sign in even steps:
4 = 4
4 - 8 = -4
4 - 8 + 12 = 8
4 - 8 + 12 - 16 = -8
...
Some examples:
for n in range(4, 100, 4):
print("%d -> %d" % (n, sumSeries(n)))
Output:
4 -> 4
8 -> -4
12 -> 8
16 -> -8
20 -> 12
24 -> -12
28 -> 16
32 -> -16
36 -> 20
40 -> -20
44 -> 24
48 -> -24
52 -> 28
56 -> -28
60 -> 32
64 -> -32
First of all, know that your series sum has a closed form.
def series_sum(n):
sign = 1 if n % 2 else -1
value = (n - 1) // 2 * 4 + 4
return sign * value
series_sum(1) # 4
series_sum(2) # -4
series_sum(3) # 8
But in general, infinite series are a good usecase for generators.
def series():
value = 0
sign = -1
while True:
value += 4
sign *= -1
yield sign * value
s = series()
next(s) # 4
next(s) # -8
next(s) # 12
Thus for getting the sum you can do this.
s = series()
def sum_series(n, s):
return sum(next(s) for _ in range(n))
sum_series(5, s) # 12
An interesting question asked in the comment is also, given some value, how can we recover the sum up until that value is reached in the series. The generator approach is well suited for these kind of problems.
from itertools import takewhile
def sum_until(val):
return sum(x for x in takewhile(lambda x: -val <= x <= val, series()))
sum_until(12) # 8
Python can be used to easily compute mathematical sequences and series.
We find the sum of all values computed up to and including n
Given
the following mathematical components:
generating function (A)
sample alternating arithmetic sequence (B)
summation equation (C)
We now implement two approaches A and C verified by B.
Code
import itertools as it
n = 8
Generating Function, A
seq = [(-1)**(i + 1)*(4 * i) for i in range(1, n + 1)]
sum(seq)
# -16
Summation Equation, C
def f(n):
if n == 1:
return 1
elif n % 2 == 0:
return -n // 2
else:
return (n + 1) // 2
4*f(n)
# -16
Details
Generating Function
This first approach simply sums an arithmetic sequence generated by a list comprehension. The signs of values alternate by the expression (-1)**(i + 1):
seq
# [4, -8, 12, -16, 20, -24, 28, -32]
Similarly, an infinite sequence can be made using a generator expression and itertools.count:
inf_seq = ((-1)**(i + 1)*(4 * i) for i in it.count(1))
sum(it.islice(inf_seq, n))
# -16
Here the sum is returned for a slice of n values. Note, we can use the take itertools recipe and itertools.accumulate to compute some arbitrary number of summations, e.g. 10 sums (see also itertools.takewhile).
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(it.islice(iterable, n))
inf_seq = ((-1)**(i + 1)*(4 * i) for i in it.count(1))
list(take(10, it.accumulate(inf_seq)))
# [4, -4, 8, -8, 12, -12, 16, -16, 20, -20]
Summation Equation
The second approach comes from inspection, where a pattern is determined from the outputs of a sample sequence:
n 4n f(n) 4f(n)
--- ---- ---- -----
1 4 1 -> 4
2 -8 -1 -> -4
3 12 2 -> 8
4 -16 -2 -> -8
5 20 3 -> 12
6 -24 -3 -> -12
7 28 4 -> 16
8 -32 -4 -> -16
9 36 5 -> 20
10 -40 -5 -> -20
For an arbitrary final value n, a value of the sequence is generated (4n). When multiplied with some unknown function, f(n), a resultant sum is computed (4f(n)). We determine a pattern for f(n) by deducing the relationship between the sequence values and expected sums. Once determined, we directly implement a function that computes our desired sums.
Highlights
Mathematical sequences can be generated from list comprehensions.
Infinite sequences can be made from generator expressions.
Mathematical series/generating functions can be computed using reducing functions, e.g. sum(), operator.mul(), etc. applied to sequences.
General summation equations can be implemented as simple Python functions.
As #John Coleman pointed out, sum += i - (i+2) produces one result not as you expected.
Below is my solution:
Using if else to determinate the sign, then sum up. at last, put it into another loop to create the series you'd like.
n = 9
print('N='+str(n), [sum([index*4 if index%2 else index*-4 for index in range(1, num+1)]) for num in range(1, n+1)])
n = 8
print('N='+str(n), [sum([index*4 if index%2 else index*-4 for index in range(1, num+1)]) for num in range(1, n+1)])
Output:
N=9 [4, -4, 8, -8, 12, -12, 16, -16, 20]
N=8 [4, -4, 8, -8, 12, -12, 16, -16]
[Finished in 0.178s]
This question already has answers here:
Prime factorization - list
(17 answers)
Closed 6 years ago.
So my program is supposed to find the prime factors of an integer and then the contents of the integer array is printed out and the values in the array are supposed to be multiplied together (giving you the original number)
this is what it is supposed to look like
Prime Factorization Program
Enter an integer > 1: 210
Prime Factors
2
3
5
7
Check Product = 210
this is my code and my results
def main():
a = [0]*20
print("Prime Factorization Program")
print()
num = eval(input("Enter an integer > 1: "))
count = 0
for k in range(1,num):
if num % k == 0:
a[count]= k
count = count + 1
mySum = 0
for k in range(count):
mySum = mySum + a[k]
print()
print("Prime Factors")
for k in range(count):
print(a[k])
print("Check Product =",mySum)
main()
here are my result
Prime Factorization Program
Enter an integer > 1: 210
Prime Factors
1
2
3
5
6
7
10
14
15
21
30
35
42
70
105
Check Product = 366
Problem - If f is a factor, you don't want to count multiples of f.
Solution - Once you identify a factor f, divide n by f.
Example - 210 is divisible by 2; divide by 2 and thereafter process 105. That ensures you don't count any more multiples of 2 like 6 or 10. 105 is divisible by 3; divide by 3 and continue with 35.
Problem - Prime factors can show up multiple times. 12 = 2×2×3.
Solution - If f is a factor, keep checking for it and dividing by f until you've accounted for all occurrences.
Example - 12 is divisible by 2; divide by 2 to get 6. 6 is still divisible by 2; divide by 2 again to get 3. 3 is not divisible by 2; continue to the next factor.
Because your code is printing all the factor instead of just prime factors. Below is the sample function you may refer for prime factorization:
def prime_factors(n):
prim_facs = []
d = 2
while d*d <= n:
while (n % d) == 0:
prim_facs.append(d)
n //= d
d += 1
if n > 1:
prim_facs.append(n)
return prim_facs
# Sample Example
# >>> prime_factors(210)
# [2, 3, 5, 7]
I've created a program that successfully detects whether a number is prime, or not, it also will return a list of the factors of the number if it isn't, but that part is not successful.
Here is my code:
def prime_num():
num = int(input("Give me a number...: "))
prime = True
if num == 1:
prime = False
elif num == 2:
prime = True
for x in range(2, num):
if num % x == 0:
prime = False
break
if prime == False:
print("That's not a prime number!")
factors(num)
elif prime == True:
print("That's a prime number!")
def factors(num):
factors = []
for x in range(1, num+1):
if num % x == 0:
factors.append(x)
print("The factors for " + str(num) + " are: ", factors)
for x in factors:
for y in range(1, x):
if x % y == 0:
factors.remove(x)
print("The prime factors for " + str(num) + " are: ", factors)
When I use this function with a "num" value of 25 I get this output...
prime_num()
Give me a number...: 25
That's not a prime number!
The factors for 25 are: [1, 5, 25]
The prime factors for 25 are: [1, 25]
Which isn't the correct output for prime factors, I just want it to return: [5]
(I'm not concerned about the multiplicity of the factors at this time)
However, when I try the number 50, as my "num". I get this output with a valueError:
prime_num()
Give me a number...: 50
That's not a prime number!
The factors for 50 are: [1, 2, 5, 10, 25, 50]
Traceback (most recent call last):
File "<ipython-input-19-12c785465e2a>", line 1, in <module>
prime_num()
File "C:/Users/x/Desktop/Python/Python Practice/primes.py", line 25, in prime_num
factors(num)
File "C:/Users/x/Desktop/Python/Python Practice/primes.py", line 40, in factors
factors.remove(x)
ValueError: list.remove(x): x not in list
I realize this means somehow my x isn't in factors, but I'm not sure how considering I'm specifically iterating through factors.
This should make it clear what your problem is:
factors = [1,5,25]
for x in factors:
for y in range(1,x):
print x,y
5 1
5 2
5 3
5 4
25 1
25 2
25 3
25 4
25 5
25 6
25 7
25 8
25 9
25 10
25 11
25 12
25 13
25 14
25 15
25 16
25 17
25 18
25 19
25 20
25 21
25 22
25 23
25 24
You're iterating over your factors in such a way that you ignore 1 and ignore the x % x combination. range(1,1) is the empty list, and then you simply stop short because you've increased the start point by 1 (from zero) but not the end point, leaving what you iterate over too short.
The reason you get a ValueError is because any non-square number (ie, not 4, 9, 16, 25, etc.) will be removed twice. For 6, for example, it will remove for the 2,3 combo and when it gets to the 3,2 combo it's already been removed, thus the error. One way to fix this is to make the code only go halfway minus one to your total, so that inverted numbers aren't removed twice. For example, stop at 2 for 6, 4 for 10, etc.