Search code examples
pythonmathsquare-root

How to change √243 to 9√3 in python? And how to change squared root generally?


I have a math/python question, how to change big number in squared root, to small number (but still keeping the value), for example √243 to 9√3?

And I have another question, how to use it in my code?

Code:

import math
dl=int(input("Podaj długość: "))
c=input("Który bok: przypdl, przypkr, przec: ")
def find(x):
    global przypkr
    global przec
    global przypdl
    if c=="przec":
        przec=x
        przypkr=x/2
        przypdl=przypkr*math.sqrt(3)
    elif c=="przypkr":
        przypkr=x
        przypdl=x*math.sqrt(3)
        przec=x*2
    else:
        przypdl=x
        przypkr=x/math.sqrt(3)
        przec=przypkr*2
    print(f'przeciwprostokątna: {przec}, krótsza przyprostokątna: {przypkr}, dłuższa przyprostokątna: {przypdl} √{przypdl*przypdl}')
find(dl)

def obw():
    print(f'Obwód równa się: {przec + przypkr + przypdl} lub {przec + przypkr} + √{przypdl*przypdl}')

obw()

Solution

  • The way I thought of this is that we can recursively remove square factors from the root.

    e.g.

            243
            / \
         3^2   27
              /  \
            3^2   3
    

    The final result on the right (i.e. 3) will be the simplified root, since we've removed all the square factors. The numbers on the left (3 * 3 == 9) will be what we take out the root.

    First, we need a way of telling whether a number is square. From another question:

    import math
    
    def is_square(i: int) -> bool:
        return i == math.isqrt(i) ** 2
    

    Next, we need to be able to determine the factors of a number. I put together something rudementary here, although it can certainly be made more efficient (better examples here):

    def factors(i: int) -> list[int]:
        factors = []
        for number in range(1, i + 1):
        if i % number == 0:
            factors.append(number)
        return factors
    

    Now, we can generate the factors of a number which are square:

    >>> [a for a in factors(20) if is_square(a)]
    [1, 4]
    

    Putting this all together, we can generate the number outside the square root. Our base case is when the root is already simplified. This means that its only square factor is 1.

    Otherwise, we generate what the number outside should be after removing one factor, and we keep repeating this process.

    def outside(i: int) -> int:
        square_factors = [a for a in factors(i) if is_square(a)]
        # Factors are sorted in increasing order.
        # Therefore, take any factor that's not 1
        factor = square_factors[-1]
        if factor == 1:
            return 1
        # Double slash usage e.g. 7.0 => 7. Could alternatively use int
        return int(math.sqrt(factor) * outside(i // factor))
    
    >>> outside(243)
    9  # 9 root 3
    >>> outside(20)
    2  # 2 root 5
    

    Finally, we need to generate the number inside the root. e.g. If its outside number is 3, we divided the original number by 3^2 == 9 to get the simplified root.

    def inside(i: int) -> int:
        return i // (outside(i) ** 2)
    
    >>> inside(20)
    >>> 5  # 2 sqrt 5
    
    >>> inside(243)
    >>> 3  # 9 sqrt 3
    

    Putting this all together:

    def simplify(i: int) -> tuple[int, int]:
        return outside(i), inside(i)
    
    >>> simplify(243)
    (9, 3)  # 9 sqrt 3
    >>> simplify(10)
    (1, 10)  # 1 sqrt 10
    >>> simplify(20)
    (2, 5)  # 2 sqrt 5