Hi I have task that that I dont know how to do. Basically I need to write primal numberswhere is only difference by 2 numbers, only primal number which is either two more or two less than another prime number and then print every pair of these primes that are less than or equal to 100.
Here is how it should look like.
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
Here is my code.I don't know how to eliminate these that are more than 2
for b in range(1, n):
if b>2:
for p in range(2, b):
if (b%p) ==0:
break
else:
print(b )
Without changing your existing code, you could do:
lastprime = 2
for b in range(1, n):
if b>2:
for p in range(2, b):
if (b%p) ==0:
break
else:
if b == lastprime + 2:
print(lastprime, b)
lastprime = b
It should be a bit more efficient by using Sieve of Eratosthenes:
sieve = [True for _ in range(n + 1)]
current_number = 2
while (current_number * current_number <= n):
if (sieve[current_number] == True):
for i in range(current_number * current_number, n + 1, current_number):
sieve[i] = False
current_number += 1
primes = [index for index in range(2, n + 1) if sieve[index]]
for i in range(len(primes) - 1):
first = primes[i]
second = primes[i + 1]
if first + 2 == second:
print(f'{first} {second}')
or even more efficient:
sieve = [False] * 2 + [True] * (n - 1)
for number in range(int(n ** 0.5 + 1.5)):
if sieve[number]:
for i in range(number * number, n + 1, number):
sieve[i] = False
primes = [i for i, prime in enumerate(sieve) if prime]
for i, first in enumerate(primes[:-1]):
second = primes[i + 1]
if first + 2 == second:
print(f'{first} {second}')
Explanation:
https://www.geeksforgeeks.org/sieve-of-eratosthenes/
Related
Is there a way to list super primes (primes in a prime position wikipedia article) between 1 and n using NumPy.
I got this without Numpy, is that okay?
here is the code based on
Sieve of Atkin
import math
is_prime = list()
limit = 100
for i in range(5, limit):
is_prime.append(False)
for x in range(1, int(math.sqrt(limit)) + 1):
for y in range(1, int(math.sqrt(limit)) + 1):
n = 4 * x ** 2 + y ** 2
if n <= limit and (n % 12 == 1 or n % 12 == 5) and n <= len(is_prime):
# print "1st if"
is_prime[n] = not is_prime[n]
n = 3 * x ** 2 + y ** 2
if n <= limit and n % 12 == 7:
# print "Second if"
is_prime[n] = not is_prime[n]
n = 3 * x ** 2 - y ** 2
if x > y and n <= limit and n % 12 == 11:
# print "third if"
is_prime[n] = not is_prime[n]
for n in range(5, int(math.sqrt(limit))):
if is_prime[n]:
for k in range(n ** 2, limit + 1, n ** 2):
if k <= len(is_prime):
is_prime[k] = False
for n in range(5, limit):
if n < len(is_prime) and is_prime[n]:
print(n)
Numpy Code Version
Sieve modification of Numpy Sieve by user2357112 supports Monica
import numpy as np
def sieve(n):
'''
Sieve of Erastosenes using numpy
'''
flags = np.ones(n, dtype=bool) # Set all values to True
# Set 0, 1, and even numbers > 2 to False
flags[0] = flags[1] = False
flags[4:n:2] = False
for i in range(3, n, 2):
# Check for odd primes
if flags[i]:
flags[i*i::i] = False
return np.flatnonzero(flags) # Indexes of True are prime
def superPrimes(n):
'''
Find superprimes
'''
# Find primes up to n using sieve
p = sieve(n)
# p(i) denotes the ith prime number, the numbers in this sequence are those of the form p(p(i))
# Want to find numbers we can index in the list (i.e. has to be less than len(p))
indexes = p[p < len(p)] # base 1 indexes within range
return p[indexes-1] # Subtract 1 since primes array is base 0 indexed
Test
print(superPrimes(200))
# Output: [ 3 5 11 17 31 41 59 67 83 109 127 157 179 191]
#!/usr/local/bin/python3.6
def isPrime(n):
if n == 1:
print("1 is a special")
return False
for x in range(2, n):
if n % x == 0:
print("{} is equal to {} * {}".format(n, x, n // x))
return False
else:
print(n, " is a prime number")
return True
for n in range(1, 21):
isPrime(n)
isPrime(2)
isPrime(21)
isPrime(25)
and the result it gives to me is:
1 is a special
3 is a prime number
4 is equal to 2 * 2
5 is a prime number
6 is equal to 2 * 3
7 is a prime number
8 is equal to 2 * 4
9 is a prime number
10 is equal to 2 * 5
11 is a prime number
12 is equal to 2 * 6
13 is a prime number
14 is equal to 2 * 7
15 is a prime number
16 is equal to 2 * 8
17 is a prime number
18 is equal to 2 * 9
19 is a prime number
20 is equal to 2 * 10
21 is a prime number
25 is a prime number
there is no result of (2),
and also this is result of 'even-odd' numbers, not 'isPrime' , because in the code 'for x in range(2, n)' , it has calculated only with number 2 for x
what is wrong in my code ?
Don't return True form the first iteration. Not being divisible by 2 does not make it prime:
for x in range(2, n): # it would be enough to loop to sqrt(n)
if n % x == 0:
# you know it is NOT prime after first divisor found
return False
# you only know it IS prime after you tried all possible divisors
return True
Do this:
def isPrime(n):
if n == 1:
print("1 is a special")
return False
for x in range(2, n):
if n % x == 0:
print("{} is equal to {} * {}".format(n, x, n // x))
return False
print(n, " is a prime number")
return True
for n in range(1, 21):
isPrime(n)
for x in range(2, n):
if n % x == 0:
print("{} is equal to {} * {}".format(n, x, n // x))
return False
else:
print(n, " is a prime number")
return True
Watch the indentation: else is now is in aligned with for (not with if), and it should solve your problem. Else means that the x got iterated over n, so n%x was never 0 => you got a prime
In the following code snippet I am finding the sum of digits of all odd number between the interval [a,b]
def SumOfDigits(a, b):
s = 0
if a%2 == 0:
a+=1
if b%2 == 0:
b-=1
for k in range(a,b+1,2):
s+= sum(int(i) for i in list(str(k)))
return s
Is there an efficient way to accomplish the same?
Any patterns, which is leading to a clear cut formula.
I did search in https://oeis.org
Avoid all the overhead of conversion to and from strings and work directly with the numbers themselves:
def SumOfDigits(a, b):
result = 0
for i in range(a + (not a % 2), b + 1, 2):
while i:
result += i % 10
i //= 10
return result
Of course there is a pattern. Let's look at the problem of summing up the digitsums of all – odd and even – numbers between a and b inclusively.
For example: 17 to 33
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
The middle section gives you the sum of all digits from 0 to 9 (45) plus ten times 2. The left section is 7 + 8 + 9 plus three times 1 and the right the sum of 0 + 1 + 2 + 3 plus four times 3.
The middle section can comprise several blocks of ten, for example if you calculate the range between 17 and 63, you get 40 times 45 plus ten simes the the digitsums from 2 to 5.
This gives you a recursive algorithm:
def ssum(n):
return n * (n + 1) // 2
def dsum(a, b):
res = 0
if a == b:
while a:
res += a % 10
a //= 10
elif a < b:
aa = a // 10
bb = b // 10
ra = a % 10
rb = b % 10
if aa == bb:
res += ssum(rb) - ssum(ra - 1)
res += (rb - ra + 1) * dsum(aa, bb)
else:
if ra > 0:
res += 45 - ssum(ra - 1)
res += (10 - ra) * dsum(aa, aa)
aa += 1
if rb < 9:
res += ssum(rb)
res += (rb + 1) * dsum(bb, bb)
bb -= 1
if aa <= bb:
res += 45 * (bb - aa + 1)
res += 10 * dsum(aa, bb)
return res
Now let's extend this to include only odd numbers. Adkust a so that it is even and b so that it is odd. Your sum of digit sums now runs over pairs of even and odd numbers, where even + 1 == odd. That means that the digitsum of the odd number id one more than the even number, because all except the last digits are the same and the last odd digit is one more than the even digit.
Therefore:
dsum(a, b) == oddsum + evensum
and:
oddsum - evensum == (b - a + 1) // 2
The function to sum the digitsums of all odd numbers is then:
def oddsum(a, b):
if a % 2: a -= 1
if b % 2 == 0: b -= 1
d = (b - a + 1) // 2
return (dsum(a, b) + d) // 2
When I looked at your comment about OEIS, I've noticed that the algorithm can probably be simplified by writing a function to sum the digits from all numbers from zero to n and then calculate the difference dsum(b) - dsum(a). There are probably more opportunities for optimisation.
So I have this Collatz conjecture assignment. Basically I have to write a program to which I give number and it will calculate Collatz conjecture for it. Here is my problem though: the number that will come out will be written like this :
12
6
3
10
5
16
8
4
2
1
When they should be in list like this [12, 6, 3, 10, 5, 16, 8, 4, 2, 1].
And here is my code:
n = int(input("The number is: "))
while n != 1:
print(n)
if n % 2 == 0:
n //= 2
else:
n = n * 3 + 1
print(1)
You have to store the numbers in a list
result = []
while n != 1:
result.append(n)
if n % 2 == 0:
n //= 2
else:
n = n * 3 + 1
result.append(n)
print result
This is also an option. A silly one, but still:
n = int(input("The number is: "))
print('[', end='')
while n != 1:
print(n, end=', ')
if n % 2 == 0:
n //= 2
else:
n = n * 3 + 1
print('1]')
A recursive version, just for fun:
number = int(input("the number is: "))
def collatz(n):
if n == 1:
return [n]
elif n % 2 == 0:
return [n] + collatz(n/2)
else:
return [n] + collatz((3*n)+1)
print collatz(number)
This is meant to calculate the smallest common multiple of 1-20.
I can't seem to figure out why the while loop won't end. Can anyone help me out?
i = 1
j = 1
factors = 0
allfactor = False
while allfactor == False:
while j < 21:
if i % j == 0:
factors = factors + 1
j = j + 1
else:
break
if factors == 20:
allfactor = True
break
else:
i = i + 1
j = 1
factors = 0
The least common multiple of the numbers 1..20 is 232792560.
To get to that number you just need to look at the numbers 1 to 20. You need at least all prime numbers: 2, 3, 5, 7, 11, 13, 17 and 19.
In addition, you need another 2 to calculate 4, and two more 2s for 16. To get a 9 you also need another 3.
So you end up with:
2 * 2 * 2 * 2 * 3 * 3 * 5 * 7 * 11 * 13 * 17 * 19 = 232792560
And you can easily confirm that using Python:
>>> all(map(lambda x: 232792560 % x == 0, range(1, 21)))
True
I.e. all numbers are divisors of said number; and per the proof above (its construction) there is no smaller number.