2

I'm trying to make a function in python that will simplify the number into an integer under the root. For example:

  • √(27) = 3 √(3)
  • √(567) = 9 √(7)

I have written the following function, but it's working partially, as I think the while loop isn't effective. Any help please?

def sqrt2(num):
    numbers=[]
    roots=[]
     #i=1-11
    while num>1:    
        for i in range(1,num+1):
            if num%i==0:    
                num=num//i  
                if num%i==0: 
                    num=num//i
                    numbers.append(i)
                else:
                    roots.append(i)
        break

    result=1
    for i in numbers:
        result= result*i
    u_root=1
    for j in roots:
        u_root=u_root*j

    print (result,"sqrt (",u_root,")")  
Blckknght
  • 100,903
  • 11
  • 120
  • 169

3 Answers3

2

This loop simply tries division by 2*2, 3*3, 4*4, etc. until it finds a divisor or until the divisor is too large for the divided number.

The only interesting part is the recursion. If a partial result is found, we try to simplify the smaller number. E.g. 567 = (3*3)*63, and then 63 = (3*3)*7. These two results combined give (9*9)*7.

def my_sqrt(num):
    for i in range(2, num):
        div, mod = divmod(num, i*i)
        if mod == 0:
            sq1, sq2 = my_sqrt(div)
            return (i * sq1, sq2)
        if div == 0:
            break
    return (1, num)

print(my_sqrt(27))
print(my_sqrt(567))
VPfB
  • 14,927
  • 6
  • 41
  • 75
2

here's my little code made for math homework

def sqr_sim(und_root):
    und_root = int(und_root)
    und_root0 = round(und_root)
    rt_fc = []
    coef = 1
    if und_root < 0:
        return None
    elif und_root == 0:
        return 0
    else:
        for i in range(2, und_root0):
            if und_root%(i**2) == 0:
                rt_fc.append(i)
                und_root /= i**2

                for i0 in range(2, und_root0):
                    if und_root%(i0**2) == 0:
                        rt_fc.append(i0)
                        und_root /= i0**2

        for ele in rt_fc:
            coef *= ele
        print('the final solution is',
              coef, '√', und_root)

sqr_sim(input())
Christopher Peisert
  • 21,862
  • 3
  • 86
  • 117
  • Why the double loop? `for i in range(2, und_root0): ... for i0 in range(2, und_root0): ...` – Mr. E Mar 14 '16 at 15:08
  • Hi, welcome to SO. Please don't just dump code as an answer. Explain your train of thought so we can better understand what you've done. Thanks. – Cthulhu Mar 14 '16 at 15:13
0

If your indentation is actually as it appears in the question, your break statement needs to be indented more. It should be breaking out of the for loop when the first if is hit, not breaking out of the while loop.

But there's another issue with the code. You're starting the for loop with i being 1, but num % 1 will always be true in that case, leading to an infinite loop. You should skip i=1 and loop on range(2, num+1):

while num>1:    
    for i in range(2,num+1):  # start range with 2
        if num%i==0:    
            num=num//i  
            if num%i==0: 
                num=num//i
                numbers.append(i)
            else:
                roots.append(i)
            break  # increase indent on this line by two levels!
Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • But it sill doesn't get all dividers. It skips a number if present 4 times. – lilezek Oct 17 '15 at 20:38
  • 1
    It shouldn't. If you break out of the `for` loop, it will restart with `i` being `1` and count back up to the `i` value that was being matched again. That's perhaps not terribly efficient, but it will work. – Blckknght Oct 17 '15 at 20:44
  • Ah, there was another bug where `1` was aways being found as a divisor. Skipping 1 and starting with 2 avoids an infinite loop. – Blckknght Oct 17 '15 at 20:51