0

This my python code it's working fine for small values as in primary testcases, but producing Memory Error due to large integer values. How can remove the Memory Error or how do I perform operations with large integers in python please?

#taking input testcases T
n=int(raw_input())

#taking value range upto iterate and find reversible numbers
_input_var = [int(raw_input()) for i in range(0,n)]


#function will reverse the number and return
def reverse(num):
    return int(str(num)[::-1])

#function will check odd confirmation for every digit 
def isDigitOdd(num):
    lista = str(num)
    for i in lista:
        if int(i)%2==0:
            flag = False
            return flag
        else:
            flag = True
    return flag

#main method
def main(_iter):    
    count=0
    for i in range(0,_iter):
        k = i + reverse(i)
        if i%10!=0 and isDigitOdd(k):
            count+=1
    print count

#calling main method for N number ranges
for i in _input_var:
    main(i)
12
  • Please be more specific. Exactly which value of n gives you an error? Show the entire callback. Commented Jun 23, 2016 at 16:19
  • thanks i will try with xrange and tell. Commented Jun 23, 2016 at 16:19
  • nope! , still getting timeout on other testcases. Commented Jun 23, 2016 at 16:24
  • @RISHABMITTAL timeouts have nothing to do with memory issues. Did xrange solve the Memory Error issue? If yes, than your question is answered. Improving speed is a different question that is related to your algorithm and optimisations. Commented Jun 23, 2016 at 16:27
  • 3
    @RISHABMITTAL - Suppose it takes only a nanosecond for each cycle through the main loop. That means it will take 10^9 seconds (almost 32 years) to finish in the case of 10^18. Note that there is no way the test computer will calculate n+reverse(n) in a nanosecond, let alone checking whether each digit in the sum is odd. A brute force solution will take several centuries to arrive at an answer. You cannot use brute force to solve this problem. Commented Jun 23, 2016 at 18:15

2 Answers 2

2

Most likely, you run out of memory when a big number is passed to range, because it has to build the entire list in memory. Replace range calls with xrange.

def main(_iter):    
    count=0
    for i in xrange(0,_iter):
        k = i + reverse(i)
        if i%10!=0 and isDigitOdd(k):
            count+=1
    print count

xrange is a lazy generator that, similarly to range in Python 3, has O(1) memory complexity. xrange uses a 64-bit C long int on 64-bit platforms to store internal state, that is the limit is almost ±10^19 (it throws OverflowError if a number exceeds that limit). Anyway, as I've already mentioned in the comments (along with other users) your algorithm is too naïve to handle a big input. You must reduce the asymptotic complexity. Something like O(log(n)) should do just fine.

P.S. Some minor optimisations

def isDigitOdd(num):
    return all(int(digit) % 2 for digit in str(num))

def main(_iter):    
    print(sum(i % 10 and isDigitOdd(i+reverse(i)) for i in xrange(0,_iter)))
Sign up to request clarification or add additional context in comments.

2 Comments

your code is returning 0 0 value on providing 2 1000 948 as input.
@Bhansa fixed that
0

It's likely this line

for i in range(0,_iter)

This will create a list of length _iter, which will be massive for large values. You actually don't need to store the whole list; you only need to increment a single integer. Instead, use xrange, which produces a generator that will only create and store one integer at a time:

for i in xrange(0,_iter)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.