Memory error Using intertool in python - python

i write a programme that i input 10 for example and it find the odd number first and the even number and put them in a list [1,3,5,7,9,2,4,6,8,10] and input another number which choose the number in the list for example 3 so it print 5 and so on so i write a code like that
from itertools import count
n,y=map(int, raw_input().split()) # Input the 2 numbers
listaa=[0,] # list to save
for x in count(1,1):
if x%2!=0:
listaa.append(x)
if x==n:
break
for h in count(1,1):
if h%2==0:
listaa.append(h)
if h==n:
break
res=listaa[y]
print res # it print the number that is in the Array or list
but when i submit the code on the online judge it try this number 1000000000000 500000000001 so it get RUNTIME_ERROR then i try this on my eclipse i get Memory Error Note i first try the Xrange but i get error when i search found the Generator so i try it and use count instead of Xrange note the Run time limit for each test case is 1 second

you cannot solve this problem using that approach because the list is very big also it will time limit the test case you suggested 1000000000000 500000000001 contains approximately 4*10^12 numbers which needs more than a terabyte of ram.
so don't use a list use a math formula instead.
sample code
n,y=map(int, raw_input().split())
first_odd = 1
last_odd = n if n%2 == 1 else n-1
n_odd = (last_odd-first_odd)/2 + 1
if y <= n_odd:
print first_odd + 2*(y-1)
else:
y -= n_odd
print 2+2*(y-1)

Related

Creating a function that returns prime numbers under a given maximum?

Instructions are to write a function that returns all prime numbers below a certain max number. The function is_factor was already given, I wrote everything else.
When I run the code I don't get an error message or anything, it's just blank. I'm assuming there's something I'm missing but I don't know what that is.
def is_factor(d, n):
""" True if `d` is a divisor of `n` """
return n % d == 0
def return_primes(max):
result = []
i = 0
while i < max:
if is_factor == True:
return result
i += 1
You should test each i against all divisors smaller than math.sqrt(i). Use the inner loop for that. any collects the results. Don't return result right away, for you should fill it first.
def return_primes(max):
result = []
for i in range(2, max):
if not any(is_factor(j, i) for j in range(2, int(math.sqrt(i)) + 1)):
result.append(i)
return result
print(return_primes(10))
As a side note, use for and range rather than while to make less mistakes and make your code more clear.
The reason that your code is returning blank when you run it, is because you are comparing a function type to the value of True, rather than calling it.
print(is_factor)
<function is_factor at 0x7f8c80275dc0>
In other words, you are doing a comparison between the object itself rather than invoking the function.
Instead, if you wanted to call the function and check the return value from it, you would have to use parenthesis like so:
if(is_factor(a, b) == True):
or even better
if(is_factor(a, b)):
which will inherently check whether or not the function returns True without you needing to specify it.
Additionally, you are not returning anything in your code if the condition does not trigger. I recommend that you include a default return statement at the end of your code, not only within the condition itself.
Now, in terms of the solution to your overall problem and question;
"How can I write a program to calculate the prime numbers below a certain max value?"
To start, a prime number is defined by "any number greater than 1 that has only two factors, 1 and itself."
https://www.splashlearn.com/math-vocabulary/algebra/prime-number
This means that you should not include 1 in the loop, otherwise every single number is divisible by 1 and this can mess up the list you are trying to create.
My recommendation is to start counting from 2 instead, then you can add 1 as a prime number at the end of the function.
Before going over the general answer and algorithm, there are some issues in your code I'd like to address:
It is recommended to use a different name for your variable other than max, because max() is a function in python that is commonly used.
Dividing by 0 is invalid and can break the math within your program. It is a good idea to check the number you are dividing by to ensure it is not zero to make sure you do not run into math issues. Alternatively, if you start your count from 2 upwards, you won't have this issue.
Currently you are not appending anything into your results array, which means no results will be returned.
My recommendation is to add the prime number into the results array once it is found.
Right now, you return the results array as soon as you have calculated the first result. This is a problem because you are trying to capture all of the prime numbers below a specific number, and hence you need more than one result.
You can fix this by returning the results array at the end of the function, not in between, and making sure to append each of the prime numbers as you discover them.
You need to check every single number between 2 and the max number to see if it is prime. Your current code only checks the max number itself and not the numbers in between.
Now I will explain my recommended answer and the algorithm behind it;
def is_factor(d, n):
print("Checking if " + str(n) + " is divisible by " + str(d))
print(n % d == 0)
return n % d == 0
def return_primes(max_num):
result = []
for q in range(2, max_num+1):
count_number_of_trues = 0
for i in range(2, q):
if(i != q):
if(is_factor(i, q)):
print("I " + str(i) + " is a factor of Q " + str(q))
count_number_of_trues += 1
if(q not in result and count_number_of_trues == 0):
result.append(q)
result.append(1)
return sorted(result)
print(return_primes(10))
The central algorithm is that you want to start counting from 2 all the way up to your max number. This is represented by the first loop.
Then, for each of these numbers, you should check every single number from 2 up to that number to see if a divisor exists.
Then, you should count the number of times that the second number is a factor of the first number, and if you get 0 times at the end, then you know it must be a prime number.
Example:
Q=10
"Is I a factor of Q?"
I:
9 - False
8 - False
7 - False
6 - False
5 - True
4 - False
3 - False
2 - True
So for the number 10, we can see that there are 2 factors, 5 and 2 (technically 3 if you include 1, but that is saved for later).
Thus, because 10 has 2 factors [excluding 1] it cannot be prime.
Now let's use 7 as the next example.
Example:
Q=7
"Is I a factor of Q?"
I:
6 - False
5 - False
4 - False
3 - False
2 - False
Notice how every number before 7 all the way down to 2 is NOT a factor, hence 7 is prime.
So all you need to do is loop through every number from 2 to your max number, then within another loop, loop through every number from 2 up to that current number.
Then count the total number of factors, and if the count is equal to 0, then you know the number must be prime.
Some additional recommendations:
although while loops will do the same thing as for loops, for loops are often more convenient to use in python because they initialize the counts for you and can save you some lines of code. Also, for loops will take care of the incrementing process for you so there is no risk of forgetting.
I recommend sorting the list when you return it, it looks nicer that way.
Before adding the prime factor into your results list, check to see if it is already in the list so you don't run into a scenario where multiples of the same number is added (like [2,2,2] for example)
Please note that there are many different ways to implement this, and my example is but one of many possible answers.

How do i sum from one to million using min,max,and sum? (in loop)

the question: Make a list of the numbers from one to one million, and then use
min() and max() to make sure your list actually starts at one and ends at one million. Also, use
the sum() function to see how quickly Python can add a million numbers.
So here's my initial code, I do not know how to use min max or sum in this case:
one_million = []
for numbers in range(0,1000000):
counting = numbers+1
one_million.append(counting)
print(one_million)
Do it step by step.
Make a list of the numbers from one to one million
numbers = list(range(1, 1000000 + 1)) # add 1 to upper bound since range is inclusive-exclusive
and then use min() and max() to make sure your list actually starts at one and ends at one million
assert min(numbers) == 1
assert max(numbers) == 1000000
Also, use the sum() function to see how quickly python can add a million numbers
total = sum(numbers)
print(total)
range supports min, max and sum, so you don't need any loop to do this:
numbers = range(1,1000001) #Note that range gives you a number UP TO the last number
print(max(numbers))
print(min(numbers))
print(sum(numbers))
Easy
million = [n for n in range(0, 1000000 + 1)]
million_sum = sum(million)
print(million_sum)
assert min(numbers) == 1
assert max(numbers) == 1000000
I'm assuming you're doing the Python Crash Course book because this is project 4-5. I came across your post while I was looking for documentation on min and max. I thought it was great to see someone else working on the same problem so I thought I would share my code. I came up with this:
million_list = []
for num in range(1,1_000_001):
million_list.append(num)
print(min(million_list))
print(max(million_list))
print(sum(million_list))
JeffUK's answer is nice. Thanks for the info about range not requiring a for loop.
numbers = list(range(1,1000001))
print(min(numbers))
print(max(numbers))
print(sum(numbers))
#also reading the book!

Uva The 3n + 1 Problem - Wrong Answer Python

I'm trying to solve a question from onlinejudge.org - The 3n + 1 Problem using Python.
in case the link doesn't load (that happens quite frequently), below is my summarized version of the question:
Consider the following algorithm:
input n
print n
if n = 1 then STOP
if n is odd then n <- 3n + 1
else n <- n/2
GOTO 2
Given the input 22, the following sequence of numbers will be printed
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between and including both i and j.
Sample Input
1 10
100 200
201 210
900 1000
Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174
And here's my code.
inputText = input().split()
inputList=[]
for index in range(0, len(inputText), 2):
inputList.append([int(inputText[index]), int(inputText[index + 1])])
def CycleLen(num):
chainList = [num]
while num > 1:
chainList.append(num//2 if num % 2 == 0 else 3*num + 1)
num = chainList[-1]
return len(chainList)
for listSet in inputList:
countList = []
minRange = min(listSet[0], listSet[1])
maxRange = max(listSet[0], listSet[1])
for num in range(minRange, maxRange + 1):
countList.append(CycleLen(num))
countList.sort()
print(listSet[0], listSet[1], countList[-1])
I'm aware of the memorization solution to make it more time efficient, but I planned to implement that only if the question rejected my answer for exceeding time limit. However, I'm straight up getting the wrong answer, and I have no idea why.
I used uDebug to see if there are any mistakes, and searched for other's solution. The most confusing part is how the online judge submits its input - single line by line, or all the lines at once. Different sources claim different things.
Please help. Thank you!
Given your code actually does generate the correct results for the given samples, it's a safe bet you're not handling the input data correctly. And, in fact, the problem statement states (my emphasis):
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 10,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
Hence, your code that gets only one pair will not be sufficient. The reason it only processes one pair has to do with a misunderstanding that the code:
inputText = input().split()
will give you all the input lines, as evidenced by the loop that tries to create a list of 2-tuples from each pair:
inputList=[]
for index in range(0, len(inputText), 2):
inputList.append([int(inputText[index]), int(inputText[index + 1])])
However, input() only reads one line of input (see here for details), meaning that you will only process the first line of the multi-line input. To do it properly, you need to continuously read and process lines until the file ends.
Having said that, you may also want to reconsider the use of a lists as your first step if it exceeds the time limit. It would be far easier to just maintain the current item and a count for calculating the cycle length (for the individual cycles) and just processing input lines sequentially (for the different ranges). Neither of those aspects requires an actual list.
Addressing both those list issues (and the one-line-of-input issue mentioned above), you would end up with something like:
def CycleLen(num):
# Start with one number, the one given.
curr = num
count = 1
# Until you get to 1, increase count and calculate next.
while curr > 1:
count += 1
curr = curr // 2 if curr% 2 == 0 else curr * 3 + 1
return count
while True:
# Reads a single line and splits into integers. Any problem, exit loop.
try:
inputInt = [int(item) for item in input().split()]
if len(inputInt) != 2: break
except:
break
# Find value in the range with the longest cycle then print it.
maxCycle = 0
for number in range(min(inputInt), max(inputInt) + 1):
maxCycle = max(maxCycle, CycleLen(number))
print(inputInt[0], inputInt[1], maxCycle)

Finding the product of first Million natural numbers in Python

I have just started with Python programming language. I tried to write a function which takes input either a list or multiple integers to find their product. I am trying to find the product of first million natural numbers but its displaying an MemoryError.
def product(*arg):
answer=1
if type(arg) == tuple:
arg=str(arg)
arg=arg.lstrip('[(')
arg=arg.rstrip('],)')
arg=arg.split(',')
for i in arg:
answer*=int(i)
return answer
else:
for i in arg:
answer*=int(i)
return answer
j=range(1,1000000,1)
j=list(j)
print(product(j))
Steps:
I convert the range object into list object if i am to pass a list as
argument
Now, within the function, i try to split the tuple by converting it
string.
I convert the resultant string into a list and then loop over the
elements to find the product
Q1: How to avoid the memory error as i try to find the product of first Million natural numbers?
Q2 How to improve this code?
You can use a Generator in Python.
def generate_product():
r = 1
for i in range(1,1000000):
r *= i + 1
yield r
list(generate_product())[0]
It is more memory efficient and better in terms of performance.
To calculate the product of all numbers from 1 to 1 million use a simple loop:
r = 1
for l in range(1,1000000):
r*=(i+1)
print(res)
But keep in mind that the result will be a pretty big number.
That means that your calculation might take long and the resulting number will need a lot memory.
EDIT Then i missread your question a little. This is a function that multiplies the elements in a list:
def multiply_list_elements(_list):
result = 1
for element in _list:
result*=element
return result
multiply_list_elements([1,2,3,4])
>>> 24
The memory error probably came from the huge number as #ZabirAlNazi calculated so nicely.
All of the solution is fine, but one point to make - your question is equivalent to find the factorial of 1 million.
The number of digits of n! = log10(1) + log10(2) + ... log10(n)
import math
num_dig = 1
for i in range(1,1000000):
num_dig += math.log10(i)
print(num_dig)
So, the number of digits in your answer is 5565703 (approx.).
That's only the final n, if you also want the intermediate results it will require squared memory O(m^2).
import math
ans = 1
for i in range(2,1000001):
ans *= i
print(ans)
N.B: You can approximate with logarithms and Stirling numbers with faster run-time.
A very simple solution would be:
def prod_of():
p=1
for i in range(1,1000000):
p* = i
print(p)

Why is my code giving memory error?

I am making a program where I can count the number of a in a string. This is my Code:
def repeatedString(s, n):
converged = s*n
got_it = converged[0:n]
count = 0
for x in got_it:
if "a" in x:
count += 1
return count
s = input()
n = int(input())
result = repeatedString(s, n)
print(result)
The variable s is where the string is entered, and variable n is for upto how long the string will repeat. My Code works OK, but for some reason when I give a bigger integer, it falls apart and gives me a Memory Error. For example, my input is:
a
1000000000000
It gives me this error:
Traceback (most recent call last):
File "programs.py", line 11, in <module>
result = repeatedString(s, n)
File "programs.py", line 2, in repeatedString
converged = s*n
MemoryError
How can I fix this Memory Error? If there's a better way to do it, it would also be helpful.
The problem with your code is where you do converged = s*n. In that line, you are asking the program to take the string s and allocate enough memory to fit the number of bytes in s * n, which, as you have seen, has a limit because your computer has a finite amount of free memory available (most modern-day computers only carry 4 - 16 gigabytes of RAM).
One way you can fix the memory error is by exploiting one aspect of your function - you are simply checking how many "a"'s fit in a string s repeated up to a length of n. So, instead of doing converged = s*n and subsequent modifications that require a lot of memory to store such a large string, you can instead use simple math to get the answer you are looking for.
Also, another optimization you could do is that you do not have to convert your string into an array to loop over it. Instead of doing for x in got_it, you could do for c in s.
Here is a working example of how you can accomplish what you need:
import math
def repeatedString(s, n):
if len(s) == 0:
return 0
reps = float(n) / len(s)
count = 0
for c in s:
if c == "a":
count += 1
# After testing the code, it turns out that Python does not play nicely
# with rounding UP from 0.5, so this is necessary to get the correct answer
result = count * reps
if result - math.floor(result) < 0.5:
return math.floor(result)
return math.ceil(result)
s = input()
n = int(input())
result = repeatedString(s, n)
print(result)
this program
takes a input string named s
repeats this string concatenated n times
takes only the first n charactes in the concatenated
counts how many times the letter "a" appears
you
you give the string "a"
you give the number 1000000000000
then the program should count and return 1000000000000
memmory problem
I guess this string with 1000000000000 letters "a" is too big
for the type in the python language
or for the computer memmory
the way it is
given that the program searches for the fixed occurrences of letter "a"
you passed exactly the letter "a" and the number 1000000000000
the better way is that it's not necessary a program
if you want to know how many times there is the letter "a"
in a string with 1000000000000 letters "a"
the answer is obviously 1000000000000
extra:
it would be complicated:
to rewrite the program
to search for a pattern
given as input parameter,
with variable length
AND
avoid the memmory problem
I guess I would write a program that
concatenates the "s" input just to have a length bigger than the searched pattern (if already not is)
check if the pattern occurs
after that multiply by "n"
ajust the how many times it will 'fit' in the final
one-line solution: find no of 'a' in string s, multiply with floor division of no.of repetition with the length of s + finding 'a' in the remaining length of s
s.count("a") * (n // len(s)) + s[:n % len(s)].count("a")
Thanks for all the help guys, I managed to solve the problem by handling the exception using try and except MemoryError

Categories

Resources