Writing a Python code that checks Mersenne numbers using Lucas-Lehmer test.
def lucas_lehmer(p):
my_list=[4]
value=2**p-1
lucas=4
for val in range(1, p - 1):
lucas=(lucas*lucas-2)%value
if lucas== 0:
my_list.apprend(lucas)
else:
break
print(my_list)
print(lucas)
The code shown above only show gives the result for the first iteration, regardless of the p value selected. I want to be able to display all the Lehmer test values within the given value of p, in this case 17.
If I understand your question correctly, I think the problem is not doing the append in the loop but only when p is a prime number. Your formatting is somewhat off, so I'm not 100% sure if I'm right. Additionally, you have a typo in append. I added some code to print the actual result of the primality test.
def lucas_lehmer(p):
my_list=[4]
value=2**p-1
lucas=4
for val in range(1, p - 1):
lucas = ((lucas*lucas)-2) % value
my_list.append(lucas)
if lucas == 0:
print("prime")
else:
print("composite")
print(my_list)
print(lucas)
Calling lucas_lehmer(7) leads to the following output:
prime
[4, 14, 67, 42, 111, 0]
0
Related
I'm trying to create a function that will fill in any missing numbers in between two numbers in a list. The original list must be altered and cannot be new.
For example: [13,15,20] would return [13,14,15,16,17,18,19,20].
Note that I am not allowed to use a range function.
Here's my code:
def complete(list1):
i= 0
if len(list1) > 1:
for number in list1:
if number - list1[i+1] != -1:
number += 1
list1.insert(i + 1, number)
i += 1
return list1
else:
return list1
I got a "list index out of range" error.
Here is the source of your error:
...
for number in list1:
if number - list1[i+1] != -1:
...
i += 1
Basically, there comes a point (that point being the last number in list1) when i+1 gets you out of bounds and you are not doing anything to prevent that from happening. Indexing is tricky like that, so I would like to offer an indexing-free (well, almost) approach. By the way, from your comment to Bonfire's answer, I see that the task is to change original lists in-place. While mutating arguments is considered a very poor coding practice these days, here is a relatively efficient way of doing that:
import typing as t
def complete_sequence(partial: t.List[int]) -> t.List[int]:
# edge case
if len(partial) < 2:
return partial
# a lookup table for numbers we already have
observed = set(partial)
# append numbers we don't have
start = partial[0]
stop = partial[-1]
num = start + 1
while num < stop:
if not num in observed:
partial.append(num)
num += 1
# in-place sort
partial.sort()
return partial
As you see, instead of inserting values between existing numbers (paying O(n) time for each insertion), we can simply append everything (O(1) per insertion) and sort. This not only simplifies the logic (we no longer have to track those pesky indices), but also reduces computational time-complexity from O(n^2) to O(n*log(n)).
To achieve what you want to do I have made some changes to the logic:
def complete(list1):
if len(list1) < 2 : return list1
num = list1[0]
i = -1
while num < list1[-1]:
num += 1
i += 1
if num in list1: continue
if i < len(list1) - 1:
list1.insert(i + 1, num)
else:
list1.append(num)
return list1
print(complete([13, 14, 20]))
# [13, 14, 15, 16, 17, 18, 19, 20]
print(complete([13, 14, 15]))
# [13, 14, 15]
k=int(input())
res=[2]
for i in range(2,k+1):
if i%2==0:
continue
else:
for j in range(2,i):
if i%j==0 or j%2==0 :
break
else:
res.append(i)
print(res)
This code is for finding prime numbers in a given range of numbers.
I tried to run the code but the list is having only number 2. Can anyone tell me what is happening?
If I remove j%2==0 it's working. I just want to know my mistake.
You should use your current result to accelerate your process. You only need to test divisibility by primes. But you are building a list of primes. So use it !
k=int(input())
primes=[]
for i in range(2,k+1):
if all(i%p!=0 for p in primes):
primes.append(i)
You can also improve by selecting only prime elements which are inferior to sqrt(i) like others suggested.
import math
k=int(input())
primes=[]
for i in range(2,k+1):
j=math.sqrt(i)
if all(i%p!=0 for p in primes if p<=j):
primes.append(i)
Your code had one issue, in the inner loop the or condition is incorrect, as highlighted by #kederrac. You don't need the j%2==0 as j always start from 2 and i%j==0 already covers the condition
k=int(input())
res=[2]
for i in range(2,k+1):
if i%2==0:
continue
else:
for j in range(2,i):
if i%j==0 :
break
else:
res.append(i)
print(res)
in your inner loopj variable starts from value 2 and then you have an if statement that is always True because j%2==0 is always 2%2==0 which is always True, so you always break from the first step of inner for loop iteration
you can use:
import math
k=int(input())
res=[]
for i in range(2, k+1):
for x in range(2, int(math.sqrt(i) + 1)):
if i % x == 0 :
break
else:
res.append(i)
# k = 20
output:
[2, 3, 5, 7, 11, 13, 17, 19]
for efficient prime generation, you can use the Sieve of Eratosthenes:
# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/
def _gen_primes():
""" Generate an infinite sequence of prime numbers.
"""
# Maps composites to primes witnessing their compositeness.
# This is memory efficient, as the sieve is not "run forward"
# indefinitely, but only as long as required by the current
# number being tested.
#
D = {}
# The running integer that's checked for primeness
q = 2
while True:
if q not in D:
# q is a new prime.
# Yield it and mark its first multiple that isn't
# already marked in previous iterations
#
yield q
D[q * q] = [q]
else:
# q is composite. D[q] is the list of primes that
# divide it. Since we've reached q, we no longer
# need it in the map, but we'll mark the next
# multiples of its witnesses to prepare for larger
# numbers
#
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
k=int(input())
def gen_primes(k):
gp = _gen_primes()
p = next(gp)
while p < k:
yield p
p = next(gp)
res = list(gen_primes(k))
Diving into coding for the first time and I'm trying to tackle the third Project Euler problem (finding the largest prime factor of 600851475143) and I want to write a function that simply returns the prime factors before I determine the largest one.
I cobbled together some shoddily written Python code below. It finds the factor of any number just fine but for some reason, the prime factor function always returns 3. Is there something I'm missing? Here's the code:
def factorize(j):
factors = []
print("Finding factors...")
for i in range(1, j+1):
if j % i == 0:
factors.append(i)
print("Done!")
print(factors)
return factors
def prime(n):
primes = []
for factor in n:
for p in range(1, factor+1):
for i in range (2, p):
if p % i == 0:
break
else:
primes.append(p)
print(primes)
return primes
print("Number to factor: ")
num = int(input())
num = factorize(num)
print("Now to find the primes...")
prime(num)
Thanks again for your help!
You put a return statement deep inside the nested loops of prime, so none of those loops completes an iteration.
I'm trying to write a program to find all the prime factors of a given number, and tried the following:
def factors(nr):
i = 2
factors = []
while i<nr:
if (nr%i)==0:
factors.append(i)
nr = nr/i
else:
i = i+1
return factors
My idea is the following. Start with i = 2, while i < the number, check if the module of the number and i = 0. If this is the case, add i to a list, and run the algorithm again, but now with the new number. However, my algorithm doesn't work. Any idea why?
I know that several right answers are posted on the site, but I would like to know why my program is incorrect.
Update
So if I let the programm run for example:
factors(38), yields [2].
factors(25), yields [5].
So it stops after it has added one number to the list.
The simplest change you can make to fix your problem is to change your while loop condition:
def factors(nr):
i = 2
factors = []
while i <= nr:
if (nr % i) == 0:
factors.append(i)
nr = nr / i
else:
i = i + 1
return factors
print factors(8)
print factors(9)
print factors(10)
Output
[2, 2, 2]
[3, 3]
[2, 5]
def ba(n):
pfa=[]
y=n
for i in range(n):
if (i!=0 and i!=1):
while (y%i==0):
pfa.append(i)
y=y/i
print(pfa)
I am relatively new to Python. Now, I know there are tons of better programs for prime factorization out there but I tried writing the code without any help and got stuck. Here is the code:
def is_prime(n):
i =2
while i<n:
if n%i==0:
return False
i+=1
return True
def prime_factor(n):
b = n
factor=[]
i = 2
while i<b and is_prime(i):
while n%i ==0:
factor.append(i)
n/=i
continue
i+=1
return factor
print (prime_factor(28))
The code works well for some numbers (27, 24, 12, 18 etc) but fails for 28. I get the output as [2,2] for the value 28. Where does the fault lie?
Problem in while condition:
while i<b :
while is_prime(i) and n%i ==0:
factor.append(i)
n/=i
continue
i+=1