codewars中的python解决方案could not pass time limit,需要优化

标签 python

有一个关于codewars, life without primes 的问题。我解决了,但时间问题出现了。我真的找不到更好的方法。说明是这样的;

考虑一个没有素数的数组,并且它的所有元素都没有任何素数。它将以:[1,4,6,8,9,10,14,16,18,..] 开头。索引 1 处的元素是 4。

将给出一个整数 n,任务将返回数组中该索引处的数字。例如,如上所述,solve(1) = 4。

这是我的解决方案

def solve(n):
    no_primes=[]
    a=1
    if n == 1:
        return 4
    else:
        while True:
            try:
                no_primes[n]
                break
            except IndexError:
                if is_prime(a) == True:
                    if is_num_prime(a) == False:
                        no_primes.append(a)
                a=a+1
        return no_primes[n]

def is_prime(num):
    numbers = list(map(int, list(str(num))))
    #primes=[0,2,3,5,7,9]
    non_primes=[0,1,4,6,8,9]
    return all(list(map(lambda x:x in non_primes,numbers)))

def is_num_prime(num):
    if num == 2:
        return True
    elif num >2:
        for i in range(2,num):
            if num%i == 0:
                return False
        else:
            return True
    else:
        return False

摆脱 while 循环可能会有所帮助,但我需要继续追加,直到我可以从列表中获取值。使用 range(1,n) 的递归 for 循环,其中 n 递归增加可能是一个选项,但我无论如何都写不出来。

最佳答案

您可以通过简单的步骤轻松解决此问题:

生成所有组合

你可以制作一个无穷无尽的生成器,对这些数字进行更长时间的组合

def generate_numbers():
    digits= '014689'
    for i in itertools.count(1): # ever longer number
        for x in itertools.product(digits, repeat=i): # combine the digits
            number = ''.join(x)
            if number[0] != '0':
                yield int(number)
print(list(itertools.islice(generate_numbers(), 40)))
[1, 4, 6, 8, 9, 10, 11, 14, 16, 18, 19, 40, 41, 44, 46, 48, 49, 60, 61, 64, 66, 68, 69, 80, 81, 84, 86, 88, 89, 90, 91, 94, 96, 98, 99, 100, 101, 104, 106, 108]

判断一个数是否为质数

def is_prime(num):
    if num in {0, 1,}:
        return False
    if num == 2:
        return True
    if not (num % 2):
        return False
    for i in range(3, round(num **.5 + 1), 2):
        if not (num % i):
            return False
    return True

返回第n个非质数

def solve(n):
    non_prime_solutions = (i for i in generate_numbers() if not is_prime(i))
    return next(itertools.islice(non_prime_solutions, n, None))
[solve(i) for i in (1, 2, 10, 100)]
[4, 6, 44, 644]

由于所有这些都是惰性求值的,所以应该会很快。可以优化的一件事是 is_prime

关于codewars中的python解决方案could not pass time limit,需要优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47071321/

相关文章:

Python:给定时区名称的所有可能时区缩写(反之亦然)

python - 我应该如何实现 __hash__ 和 __str__

python - 如何在Python中存储非常大的数字数组?

python - Airflow :避免任务状态=跳过

Python:最后需要一个 try-except 子句吗?

Python 检查函数是否有返回语句

python - 需要 urllib.urlretrieve 和 urllib2.OpenerDirector 一起使用

python - 列表列表的 Python 调度优化 [间隔调度]

python等效数学方程给出不同的结果

python - 如何获得python中字符串出现的次数?