Hướng dẫn prime factorization function python

Since nobody has been trying to hack this with old nice reduce method, I'm going to take this occupation. This method isn't flexible for problems like this because it performs loop of repeated actions over array of arguments and there's no way how to interrupt this loop by default. The door open after we have implemented our own interupted reduce for interrupted loops like this:

from functools import reduce

def inner_func(func, cond, x, y):
    res = func(x, y)
    if not cond(res):
        raise StopIteration(x, y)
    return res

def ireducewhile(func, cond, iterable):
    # generates intermediary results of args while reducing
    iterable = iter(iterable)
    x = next(iterable)
    yield x
    for y in iterable:
        try:
            x = inner_func(func, cond, x, y)
        except StopIteration:
            break
        yield x

After that we are able to use some func that is the same as an input of standard Python reduce method. Let this func be defined in a following way:

def division(c):
    num, start = c
    for i in range(start, int(num**0.5)+1):
        if num % i == 0:
            return (num//i, i)
    return None

Assuming we want to factor a number 600851475143, an expected output of this function after repeated use of this function should be this:

(600851475143, 2) -> (8462696833 -> 71), (10086647 -> 839), (6857, 1471) -> None

The first item of tuple is a number that division method takes and tries to divide by the smallest divisor starting from second item and finishing with square root of this number. If no divisor exists, None is returned. Now we need to start with iterator defined like this:

def gener(prime):
    # returns and infinite generator (600851475143, 2), 0, 0, 0...
    yield (prime, 2)
    while True:
        yield 0

Finally, the result of looping is:

result = list(ireducewhile(lambda x,y: div(x), lambda x: x is not None, iterable=gen(600851475143)))
#result: [(600851475143, 2), (8462696833, 71), (10086647, 839), (6857, 1471)]

And outputting prime divisors can be captured by:

if len(result) == 1: output = result[0][0]
else: output = list(map(lambda x: x[1], result[1:]))+[result[-1][0]]
#output: [2, 71, 839, 1471]

Note:

In order to make it more efficient, you might like to use pregenerated primes that lies in specific range instead of all the values of this range.

Since nobody has been trying to hack this with old nice reduce method, I'm going to take this occupation. This method isn't flexible for problems like this because it performs loop of repeated actions over array of arguments and there's no way how to interrupt this loop by default. The door open after we have implemented our own interupted reduce for interrupted loops like this:

from functools import reduce

def inner_func(func, cond, x, y):
    res = func(x, y)
    if not cond(res):
        raise StopIteration(x, y)
    return res

def ireducewhile(func, cond, iterable):
    # generates intermediary results of args while reducing
    iterable = iter(iterable)
    x = next(iterable)
    yield x
    for y in iterable:
        try:
            x = inner_func(func, cond, x, y)
        except StopIteration:
            break
        yield x

After that we are able to use some func that is the same as an input of standard Python reduce method. Let this func be defined in a following way:

def division(c):
    num, start = c
    for i in range(start, int(num**0.5)+1):
        if num % i == 0:
            return (num//i, i)
    return None

Assuming we want to factor a number 600851475143, an expected output of this function after repeated use of this function should be this:

(600851475143, 2) -> (8462696833 -> 71), (10086647 -> 839), (6857, 1471) -> None

The first item of tuple is a number that division method takes and tries to divide by the smallest divisor starting from second item and finishing with square root of this number. If no divisor exists, None is returned. Now we need to start with iterator defined like this:

def gener(prime):
    # returns and infinite generator (600851475143, 2), 0, 0, 0...
    yield (prime, 2)
    while True:
        yield 0

Finally, the result of looping is:

result = list(ireducewhile(lambda x,y: div(x), lambda x: x is not None, iterable=gen(600851475143)))
#result: [(600851475143, 2), (8462696833, 71), (10086647, 839), (6857, 1471)]

And outputting prime divisors can be captured by:

if len(result) == 1: output = result[0][0]
else: output = list(map(lambda x: x[1], result[1:]))+[result[-1][0]]
#output: [2, 71, 839, 1471]

Note:

In order to make it more efficient, you might like to use pregenerated primes that lies in specific range instead of all the values of this range.

In this tutorial, we will discuss how we can get the prime factor of the given number using the Python program. All we familiar with the prime numbers, if not then prime numbers are the number that can be divided by one or itself. For example - 1, 2, 3, 5, 7, 11, 13, ……

Finding all prime factorization of a number

If the user enters the number as 12, then the output must be '2, 2, 3, and if the input is 315; the output should be "3 3 5 7". The program must return the prime all prime factor of given number. The prime factors of 330 are 2, 3, 5, and 11. Therefore 11 is the most significant prime factor of 330.

For Example: 330 = 2 × 3 × 5 × 11.

Before writing the Python program, let's understand the following conjectures.

  • 1st Conjecture - There can be at-least one prime factor that would be less than √n in case of n is not a prime number.

Proof -There are two greater sqrt(n) numbers, then their product should also divide n but which will exceed n, which contradicts our assumption. So there can NOT be more than one prime factor of n greater than sqrt(n).

Let's see the following step to perform such an operation.

  • 2nd Conjecture - There can be AT-MOST 1 prime factor of n greater than sqrt(n).

Proof - Suppose there are two greater sqrt(n) number then their product should also divide n but which will exceed n, which contradicts our assumption. So there can NOT be more than 1 prime factor of n greater than sqrt(n).

Let's see the following step to perform such operation.

Example - Python program to print prime factors

Output:

Explanation -

In the above code, we have imported the math module. The prime_factor() function is responsible for printing the composite number. First, we get the even numbers; after this, all remaining prime factors must be odd. In for loop, the num must be odd, so we incremented i by two. A for loop will run the square root of n times.

Let's understand the following property of composite numbers.

Every composite number has at least one prime factor less than or equal to the square root.

The program will work as follows.

  • In the first step, find the least prime factor i.
  • The occurrence of i be will removed from n by repeatedly dividing n by i.
  • Repeat the above both steps for dividing n and i = i + 2. Both steps will be repetitive till n become either 1 or a prime number.

Let's understand another example where we find the largest prime factor of a given number.

Example - 2 Python program to find the largest prime factor of a given number.

Output: