'''
Created on 10-May-2021

@author: bthakur
'''
import math

class MathUtil():
    _CACHED_PRIMES = [2, 3, 5, 7, 11]
    
    @classmethod
    def permutation_expr(cls, n, k):
        return f"$\Perm{{{n}}}{{{k}}}$"
    pass

    @classmethod
    def lowest_prime_divisor(cls, *nums):
        hcf = MathUtil.hcf(*nums)
        prime_factors = MathUtil.get_prime_factors(hcf)
        if not prime_factors:
            return None
        lcf = min(list(prime_factors.keys()))
        if lcf == 1:
            return None
        return lcf
        pass
    
    @classmethod
    def highest_common_tens_exp(cls, *nums):
        hcz = 0
        while True:
            for num in nums:
                if num % 10 ** hcz != 0:
                    return 10**(hcz-1)
            hcz = hcz + 1
            pass
        
        return 10**hcz
        pass
    

    @classmethod
    def hcf(cls, *nums):
        if len(nums) < 2:
            return nums[0]
        a = nums[0]
        b = nums[1]
        l = math.gcd(a, b)
        if len(nums) == 2:
            return l
        nums = [l] + list(nums[2:])
        return MathUtil.hcf(*nums)
        pass
    
    @classmethod
    def lcm(cls, *nums):
        if len(nums) < 2:
            return nums[0]
        a = nums[0]
        b = nums[1]
        l = abs(a*b) // math.gcd(a, b)
        if len(nums) == 2:
            return l
        nums = [l] + list(nums[2:])
        return MathUtil.lcm(*nums)
    
    
    @classmethod
    def get_prime_factors(cls, n):
        primeFactors = {}
        tempN = n
        isComposite = True
        while isComposite and tempN != 1:
            isComposite = False
            for p in MathUtil._CACHED_PRIMES:
                if tempN % p == 0:
                    primeFactors[p] = primeFactors.get(p, 0) + 1
                    tempN = tempN //p
                    isComposite = True
                    break
                pass
            pass
        if not primeFactors or tempN != 1:
            primeFactors[tempN] = primeFactors.get(tempN, 0) + 1
            
        return primeFactors
        pass
    