Hướng dẫn prime factor python - con trăn nguyên tố

Vì không ai cố gắng hack điều này bằng phương pháp

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
2 cũ, tôi sẽ lấy nghề này. Phương pháp này không linh hoạt cho các vấn đề như thế này bởi vì nó thực hiện vòng lặp của các hành động lặp đi lặp lại trên mảng các đối số và không có cách nào để làm gián đoạn vòng lặp này theo mặc định. Cửa mở sau khi chúng tôi đã thực hiện
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
3 của riêng mình cho các vòng lặp bị gián đoạn như sau:

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

Sau đó, chúng tôi có thể sử dụng một số

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
4 giống như đầu vào của phương pháp giảm python tiêu chuẩn. Hãy để điều này
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
4 được định nghĩa theo cách sau:

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

Giả sử chúng tôi muốn nhân tố số 600851475143, đầu ra dự kiến ​​của chức năng này sau khi sử dụng nhiều lần chức năng này phải là thế này:

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

Mục đầu tiên của tuple là một số mà phương thức

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
6 lấy và cố gắng chia cho ước số nhỏ nhất bắt đầu từ mục thứ hai và kết thúc với căn bậc hai của số này. Nếu không có ước số tồn tại, không có gì được trả lại. Bây giờ chúng ta cần bắt đầu với Iterator được xác định như thế này:

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

Cuối cùng, kết quả của vòng lặp là:

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)]

Và phát ra các ước số chính có thể được bắt bởi:

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:

Để làm cho nó hiệu quả hơn, bạn có thể muốn sử dụng các số nguyên tố được tạo sẵn nằm trong phạm vi cụ thể thay vì tất cả các giá trị của phạm vi này.

Vì không ai cố gắng hack điều này bằng phương pháp

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
2 cũ, tôi sẽ lấy nghề này. Phương pháp này không linh hoạt cho các vấn đề như thế này bởi vì nó thực hiện vòng lặp của các hành động lặp đi lặp lại trên mảng các đối số và không có cách nào để làm gián đoạn vòng lặp này theo mặc định. Cửa mở sau khi chúng tôi đã thực hiện
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
3 của riêng mình cho các vòng lặp bị gián đoạn như sau:

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

Sau đó, chúng tôi có thể sử dụng một số

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
4 giống như đầu vào của phương pháp giảm python tiêu chuẩn. Hãy để điều này
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
4 được định nghĩa theo cách sau:

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

Giả sử chúng tôi muốn nhân tố số 600851475143, đầu ra dự kiến ​​của chức năng này sau khi sử dụng nhiều lần chức năng này phải là thế này:

Mục đầu tiên của tuple là một số mà phương thức
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
6 lấy và cố gắng chia cho ước số nhỏ nhất bắt đầu từ mục thứ hai và kết thúc với căn bậc hai của số này. Nếu không có ước số tồn tại, không có gì được trả lại. Bây giờ chúng ta cần bắt đầu với Iterator được xác định như thế này:

Mục đầu tiên của tuple là một số mà phương thức

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
6 lấy và cố gắng chia cho ước số nhỏ nhất bắt đầu từ mục thứ hai và kết thúc với căn bậc hai của số này. Nếu không có ước số tồn tại, không có gì được trả lại. Bây giờ chúng ta cần bắt đầu với Iterator được xác định như thế này:

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

Cuối cùng, kết quả của vòng lặp là:

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)]

Và phát ra các ước số chính có thể được bắt bởi:

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:

Để làm cho nó hiệu quả hơn, bạn có thể muốn sử dụng các số nguyên tố được tạo sẵn nằm trong phạm vi cụ thể thay vì tất cả các giá trị của phạm vi này.

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

Trong hướng dẫn này, chúng tôi sẽ thảo luận về cách chúng tôi có thể có được yếu tố chính của số đã cho bằng chương trình Python. Tất cả chúng ta quen thuộc với các số nguyên tố, nếu không thì các số nguyên tố là số có thể được chia cho một hoặc chính nó. Ví dụ - 1, 2, 3, 5, 7, 11, 13,

Tìm tất cả các yếu tố chính của một số

Nếu người dùng nhập số là 12, thì đầu ra phải là '2, 2, 3 và nếu đầu vào là 315; Đầu ra phải là "3 3 5 7". Chương trình phải trả về tất cả các yếu tố chính của số đã cho. Các yếu tố chính của 330 là 2, 3, 5 và 11. Do đó, 11 là yếu tố chính đáng kể nhất là 330.

Ví dụ: 330 = 2 × 3 × 5 × 11.

  • Trước khi viết chương trình Python, hãy hiểu những phỏng đoán sau đây. - There can be at-least one prime factor that would be less than √n in case of n is not a prime number.

Phán đề 1 - Có thể có một yếu tố chính ở mức độ chính sẽ nhỏ hơn √n trong trường hợp N không phải là số nguyên tố.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).

Bằng chứng -Có hai số sqrt (n) lớn hơn, thì sản phẩm của họ cũng sẽ phân chia n nhưng sẽ vượt quá N, mâu thuẫn với giả định của chúng tôi. Vì vậy, không thể có nhiều hơn một yếu tố chính của N lớn hơn SQRT (N).

  • Hãy xem bước sau đây để thực hiện một hoạt động như vậy. There can be AT-MOST 1 prime factor of n greater than sqrt(n).

Phục giả thứ 2 - Có thể có hệ số 1 chính của N lớn hơn SQRT (N). 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).

Bằng chứng - Giả sử có hai số sqrt (n) lớn hơn thì sản phẩm của họ cũng sẽ phân chia n nhưng sẽ vượt quá n, mâu thuẫn với giả định của chúng tôi. Vì vậy, không thể có nhiều hơn 1 hệ số nguyên tố N lớn hơn SQRT (N).

Hãy xem bước sau đây để thực hiện thao tác như vậy.

Output:

Ví dụ - Chương trình Python để in các yếu tố chính

Giải trình -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.

Trong mã trên, chúng tôi đã nhập mô -đun toán học. Hàm Prime_factor () chịu trách nhiệm in số tổng hợp. Đầu tiên, chúng tôi nhận được những con số chẵn; Sau này, tất cả các yếu tố chính còn lại phải là lẻ. Trong vòng lặp, num phải kỳ lạ, vì vậy chúng tôi tăng lên hai. A for Loop sẽ chạy căn bậc hai của n lần.

Hãy hiểu thuộc tính sau của số tổng hợp.

Mỗi số tổng hợp có ít nhất một yếu tố nguyên tố nhỏ hơn hoặc bằng căn bậc hai.

  • Trong bước đầu tiên, tìm yếu tố chính nhất i.
  • Sự xuất hiện của tôi sẽ được loại bỏ khỏi N bằng cách chia liên tục n cho i.
  • Lặp lại các bước trên để chia n và i = i + 2. Cả hai bước sẽ lặp đi lặp lại cho đến khi n trở thành 1 hoặc số nguyên tố.

Hãy hiểu một ví dụ khác nơi chúng ta tìm thấy yếu tố chính lớn nhất của một số nhất định.

Ví dụ - 2 Chương trình Python để tìm hệ số chính lớn nhất của một số nhất định.

Output: