P206: A list of Goldbach compositions

给定一个整数区间,求其中所有偶数的哥德巴赫分拆。照例先写测试用例:

from python99.arithmetic.p206 import goldbach_list from python99.arithmetic.p201 import is_prime def test_goldbach_list(): assert goldbach_list(9, 20) == [[3, 7], [5, 7], [ 3, 11], [3, 13], [5, 13], [3, 17]]

这个问题分两步解:先求出整数区间内的所有偶数;再逐一求偶数的哥德巴赫拆分。关于「哥德巴赫拆分」,已在P205中详述。

代码实现:

from python99.arithmetic.p205 import goldbach


def goldbach_list(lower, upper):
    return [goldbach(even) for even in even_nums(lower, upper)]


def even_nums(lower, upper):
    for num in range(lower, upper+1):
        if num % 2 == 0:
            yield num

实现中,先构造一个生成整数区间内所有偶数的「生成器(generator)」even_nums(lower, upper)。然后用List Comprehension将偶数转换成对应的哥德巴赫拆分。List Comprehension的形式为:

[f(x) for e in l]

这里的f重用P205中实现的「哥德巴赫拆分」goldbach(n)

在大多数情况下,如一个偶数被表示为两个质数的和,则其中一个将会非常地小。在极其罕见的情况下,两个质数都大于50。现在对上面的问题做一下延伸:求指定整数区间内所大偶数大于50的哥德巴赫拆分。照例还是先写测试用例:

def test_goldbach_list2(): actual = goldbach_list(1, 2000, 50) for composition in actual: assert len(composition) == 2 assert composition[0] > 50 assert is_prime(composition[0]) == True assert composition[1] > 50 assert is_prime(composition[1]) == True

在上面的实现中稍加脩改,在求「哥德巴赫分拆」时过泸掉不大于指定值的解。在生成整数区间内偶数时也可以加过泸,及早地过泸掉不可能解。

完整代码实现:

# A list of Goldbach compositions from python99.arithmetic.p201 import is_prime from python99.arithmetic.p204 import prime_generator import math def goldbach_list(lower, upper, min_prime_factor=0): return [x for x in [goldbach(even, min_prime_factor) for even in even_nums(lower, upper, min_prime_factor*2)] if x != None] def even_nums(lower, upper, min_even): for num in range(lower, upper+1): if num > min_even and num % 2 == 0: yield num def goldbach(n, min_prime_factor): for first_prime in prime_generator(max(2, min_prime_factor+1), n//2): if n-first_prime < min_prime_factor: return None if is_prime(n-first_prime): return [first_prime, n-first_prime] return None

在生成偶数时直接过泸掉「小于指定最小质数两倍值的偶数」。因为两个质数都大于指定值,则它们的和数肯定大于指定值的两倍值。 在分拆偶数测试第一个质数时,直接跳过不大于指定值的质数。对第二个质数也要检测是否大于指定值,若不是则该偶数没有符合要求的「哥德巴赫拆分」。

results matching ""

    No results matching ""