I'm trying to find a number's max prime factor. Here is my code, but I don't know are my codes working correctly or not because I'm getting MemoryError all the time;
lst = []
for x in range(3,round(600851475143**0.5)+1):
for y in range(2,x+1):
if x%y==0:
for z in range(2,x+1):
if x%z!=0:
lst.append(x)
print (max(lst))
Here is the traceback;
>>>
Traceback (most recent call last):
File "C:--------", line 19, in <module>
lst.append(x)
MemoryError
>>>
After 20-30 seconds process, I got this error.How to avoid this one?
Edit: Actually, I guess that it may be MemoryError so as you see I put in the first range function, square root of that number 600851475143**0.5. Then I use round to aviod from float. But I still got MemoryError.
if x%y==0:
for z in range(2,x+1):
if x%z!=0:
lst.append(x)
I'm guessing what you're trying to do here is, append x to lst if x is prime. But what you're actually doing is, appending x to lst for every number less than x that isn't a factor of x. Ex. 6 will be appended twice because both 4 and 5 are not a factor of 6.
If you want to append x only when all z's are not a factor of x, then try:
if x%y==0:
if all(x%z != 0 for z in range(2, x)):
lst.append(x)
From the python documentation:
exception MemoryError
Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). The associated value is a string indicating what kind of (internal) operation ran out of memory. Note that because of the underlying memory management architecture (C’s malloc() function), the interpreter may not always be able to completely recover from this situation; it nevertheless raises an exception so that a stack traceback can be printed, in case a run-away program was the cause.
You're putting too many elements into lst.
There are more efficient prime factorization algorithms than the one you wrote, which can be looked up on wikipedia.
Related
I have been trying to solve Problem #3 in ProjectEuler in python. I have tried using recursion to get factors of my factors. But I keep on running into a recursive limit reached error for some reason. Can anyone help me out as to why its happening?
def getPrimeFactors(y):
AllFactors = [[x, int(y/x)] for x in range(1, (int(math.sqrt(y)+1))) if y%x==0]
Flattened_AF = [j for i in AllFactors for j in i]
print(AllFactors)
print(Flattened_AF)
if len(Flattened_AF)==2:
print(Flattened_AF)
return Flattened_AF
else:
PrimeFactors = [x for x in Flattened_AF if len(getPrimeFactors(x))==2]
print (f'loop in else - {PrimeFactors}')
print(max(PrimeFactors)
getPrimeFactors(4)
This is the problem as quoted in the website.
I am sorry if the code readability quality is a bit low but I had been trying to debug for a long time in vain.
When you define AllFactors for in input y, you iterate from 1, so the same number y is always contained within AllFactors. As such, when you call getPrimeFactors on the input, that same input y is passed, so this becomes an infinite loop.
Iterating from 2 instead of 1 stops the recursion error.
Also, just a tip, typically in python variables names begin with a lower case and classes begin with uppercase. There is more about naming conventions here:https://visualgit.readthedocs.io/en/latest/pages/naming_convention.html.
This is the python script that I'm trying to run:
n = 50000000000 ##50 billion
b = [0]*n
for x in range(0,n):
b[x] = random.randint(1,899999)
... But the output I'm getting is:
E:\python\> python sort.py
Traceback (most recent call last):
File "E:\python\sort.py", line 8, in <module>
b = [0]*n
MemoryError
So, what do I do now?
The size of the list you are generating (which is 50 billion not 5).
An int object instance takes 24 bytes (sys.getsizeof(int(899999)), the upper limit of your random numbers), so that list would take 50,000,000,000 * 24 bytes, which is about 1.09 TB.
In other words to create such a list you would need at least 1118 GB of RAM in your computer.
I don't know what your use case is, but you should consider a different approach to what you are trying to solve (maybe define a generator, or just don't store your numbers in memory and instead directly use the numbers in the for loop).
Since other people already answered your question here's a quick tip when dealing with big numbers: you can use "_" to separate the digits of your numbers as you wish:
n = 50_000_000_000
is the same as
n = 50000000000
but the former is much easier on the eyes
One other possibility is to increase you computers vitual memory. It helped me in my code. I had a max 3000MB virtual memory, when I increased it to 5000MB the memory error was gone.
I am trying to get an accepted answer for this question:http://www.spoj.com/problems/PRIME1/
It's nothing new, just wanting prime numbers to be generated between two given numbers. Eventually, I have coded the following. But spoj is giving me runtime-error(nzec), and I have no idea how it should be dealt with. I hope you can help me with it. Thanks in advance.
def is_prime(m,n):
myList= []
mySieve= [True] * (n+1)
for i in range(2,n+1):
if mySieve[i]:
myList.append(i)
for x in range(i*i,n+1,i):
mySieve[x]= False
for a in [y for y in myList if y>=m]:
print(a)
t= input()
count = 0
while count <int(t):
m, n = input().split()
count +=1
is_prime(int(m),int(n))
if count == int(t):
break
print("\n")
Looking at the problem definition:
In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.
Looking at your code:
mySieve= [True] * (n+1)
So, if n is 1000000000, you're going to try to create a list of 1000000001 boolean values. That means you're asking Python to allocate storage for a billion pointers. On a 64-bit platform, that's 8GB—which is fine as far as Python's concerned, but might well throw your system into swap hell or get it killed by a limit or watchdog. On a 32-bit platform, that's 4GB—which will guarantee you a MemoryError.
The problem also explicitly has this warning:
Warning: large Input/Output data, be careful with certain languages
So, if you want to implement it this way, you're going to have to come up with a more compact storage. For example, array.array('B', [True]) * (n+1) will only take 1GB instead of 4 or 8. And you can make it even smaller (128MB) if you store it in bits instead of bytes, but that's not quite as trivial a change to code.
Calculating prime numbers between two numbers is meaningless. You can only calculate prime numbers until a given number by using other primes you found before, then show only range you wanted.
Here is a python code and some calculated primes you can continue by using them:
bzr branch http://bzr.ceremcem.net/calc-primes
This code is somewhat trivial but is working correctly and tested well.
See this question for some background. My main problem on that question was solved, and it was suggested that I ask another one for a second problem I'm having:
print cubic(1, 2, 3, 4) # Correct solution: about -1.65
...
if x > 0:
TypeError: no ordering relation is defined for complex numbers
print cubic(1, -3, -3, -1) # Correct solution: about 3.8473
if x > 0:
TypeError: no ordering relation is defined for complex numbers
Cubic equations with one real root and two complex roots are receiving an error, even though I am using the cmath module and have defined the cube root function to handle complex numbers. Why is this?
Python's error messages are pretty good, as these things go: unlike some languages I could mention, they don't feel like random collections of letters. So when Python complains of the comparison
if x > 0:
that
TypeError: no ordering relation is defined for complex numbers
you should take it at its word: you're trying to compare a complex number x to see whether or not it's greater than zero, and Python doesn't know how to order complex numbers. Is 2j > 0? Is -2j > 0? Etc. In the face of ambiguity, refuse the temptation to guess.
Now, in your particular case, you've already branched on whether or not x.imag != 0, so you know that x.imag == 0 when you're testing x and you can simply take the real part, IIUC:
>>> x = 3+0j
>>> type(x)
<type 'complex'>
>>> x > 0
Traceback (most recent call last):
File "<ipython-input-9-36cf1355a74b>", line 1, in <module>
x > 0
TypeError: no ordering relation is defined for complex numbers
>>> x.real > 0
True
It is not clear from your example code what x is, but it seems it must be a complex number. Sometimes, when using complex numerical methods, an approximate solution will come up as a complex number even though the exact solution is supposed to be real.
Complex numbers have no natural ordering, so an inequality x > 0 makes no sense if x is complex. That's what the type error is about.
Attempting to solve this problem:
For a positive number n, define S(n) as the sum of the integers x, for which 1 < x < n and x^3 ≡ 1 mod n.
When n=91, there are 8 possible values for x, namely : 9, 16, 22, 29, 53, 74, 79, 81.
Thus, S(91)=9+16+22+29+53+74+79+81=363.
Find S(13082761331670030).
Of course, my code works for S(91) and when attempting to find S(13082761331670030) I get two different errors.
Here is my code:
def modcube(n):
results = []
for k in range(1,n):
if k**3%n==1:
results.append(k)
return results
This produces Overflow error: range has too many items. When I try using 'xrange' instead of 'range' I get an error stating python int too large to convert to c long. I have also just tried several other things without success.
Can anyone point me in the right direction, without telling me exactly how to solve it?
No spoilers please. I've been at it for two days, my next option is to try implementing this in Java since I'm new to Python.
I think you need to understand two concepts here:
1. integer representation in C and in Python
The implementation of Python you use is called CPython, because it is written using the C language. In C, long integers (usually) are 32 bits long. It means it can work with integers between -2147483647 and 2147483648. In Python, when an integer exceeds this range, it converts them to arbitrary precision integers, where the size of the integer is limited only by the memory of your computer. However, operation on those arbitrary integers (called long integers in Python) are order of magnitude slower than operation on 32 bits integers.
2. The difference between range and xrange:
range produces a list. If you have range(10), it stores the list [0, 1, ... 9] entirely in memory. This is why storing a list of 13082761331670030 items in memory is too mush. Assuming each number is 64 bits, it would need 93 TB of RAM to store the entire list!
xrange produces an iterator. It returns each number one by one. This way, it allows to perform operations on each number of the list without needing to store the entire list in memory. But again, performing calculations on 13082761331670030 different numbers could take more time that you think... The other thing about xrange is that it doesn't work with Python long integers; it is limited (for speed reasons) to 32 bits integers. This is why your program doesn't work using xrange.
The bottom line: Project Euler problems are (more or less) classified by degree of difficulty. You should begin by lower problems first.
You wanted hints, not a solution.
Hints:
Consider that the prime factors of 13082761331670030 is equal to the following primes: 2 x 3 x 5 x 7 x 11 x 13 x 17 x 19 x 23 x 29 x 31 x 37 x 41 x 43
Chinese remainder theorem
Just because x^3 ≡ 1 mod n does not mean that there are not other values other than 3 that satisfy this condition. Specifically, prime1 ** (prime2 - 2) % prime2
My Python solution is 86 milliseconds...