Gingerbread
Gingerbread

Reputation: 53

How can we make this code more efficient?

x=int(input("Enter an integer:"))
answer=None
cube_root_found=False
for i in range(0,abs(x)+1):
    if i**3 == abs(x):
        answer=i
        cube_root_found=True
if not cube_root_found:
    print(x,"is not a perfect cube")
else:
    if x<0:
        answer=-answer
    print("Cube root of",x,"is",answer)

I couldn't understand why we used answer=None and cube_root_found=False on the second line.And the other question is as i mentioned in the title : How can we make this code more efficient?

Upvotes: 0

Views: 99

Answers (6)

Him
Him

Reputation: 5549

checking if int(n**(1./3)) == n**(1./3) does NOT work generally, since 1/3 does not represent nicely in binary. try abs(int(n**(1./3)) == n**(1./3)) < 0.000000000001

Checking within a threshold is a normal way to check for equality in the presence of rounding errors. Note that (n+1) ** (1/3) -> n**(1/3) as n gets large, so this will give incorrect results for very very very large n.

Upvotes: 0

volcano
volcano

Reputation: 3582

Besides using break, I would suggest limiting range to abs(x)/2 - unless it's either -1, 0 or 1.

Besides, I am not sure whether Python can optimize calling abs on each cycle on the same value - most probably not, so I would pre-store abs(x)

abs_x = abs(x)
upper_limit = 2 if abs_x < 2 else abs_x / 2
for i in range(upper_limit):
    if i**3 == abs_x:
......

Upvotes: 0

A. L. Flanagan
A. L. Flanagan

Reputation: 1162

answer=None cube_root_found=False

We do this because, if x is 0, the for loops will execute 0 times. In that case, without the above code, we'll never assign a value to those variables, and

if not cube_root_found:

will fail with "NameError: name 'cube_root_found' is not defined message.

Upvotes: 0

user7032983
user7032983

Reputation:

Instead of iterating through a bunch of integers, just take the cube root of your input and check if it is an integer.

so something like this:

root = x**(1.0/3.0) return root.is_integer()

Upvotes: 1

Adam Smith
Adam Smith

Reputation: 54243

I mean, there's a mathematical solution for this -- just cube root x rather than testing everything in [0, x+1). No reason to loop in this case.

x = int(input("Enter an integer: "))
result = x ** (1/3)
if result == int(result):
    print("Cube root of", x, "is", result)
else:
    print(x, "is not a perfect cube")

Upvotes: 2

saarrrr
saarrrr

Reputation: 2897

Adding a break after cube_root_found = True will make it short-circuit when it finds an answer instead of continuing.

x=int(input("Enter an integer:"))
answer=None
cube_root_found=False
for i in range(0,abs(x)+1):
    if i**3 == abs(x):
        answer=i
        cube_root_found=True
        break
if not cube_root_found:
    print(x,"is not a perfect cube")
else:
    if x<0:
        answer=-answer
    print("Cube root of",x,"is",answer)

Upvotes: 1

Related Questions