Resolvi esse problema utilizando força-bruta, demorou 692 segundos.
O objeivo desse problema é encontrar o número primo abaixo de 1000000 que seja originado da maior sequência de números primos.
Consecutive prime sumLink para a pergunta: https://projecteuler.net/problem=50
Problem 50
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13
This is the longest sum of consecutive primes that adds to a prime below one-hundred.
The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.
Which prime, below one-million, can be written as the sum of the most consecutive primes?
Criei o seguinte script para resolver o problema:
def is_prime(n): if n == 2 or n == 3: return True if n < 2 or n%2 == 0: return False if n < 9: return True if n%3 == 0: return False r = int(n**0.5) f = 5 while f <= r: #print('\t',f) if n%f == 0: return False if n%(f+2) == 0: return False f +=6 return True # lista que armazena todos os números primos até o limite desejado que no caso do problema é < 1000000 lista_primos = [] # número máximo pra verificar, no caso do problema é 1000000 limite = 1000000 # preenche a lista lista_primos com os números primos até o valor da variável limite for x in range(1, limite): if is_prime(x): lista_primos.append(x) def maior_numero_soma_seq(lista): i = 0 lista.reverse() maior_numero_lista = max(lista) maior_sequencia = 0 maior_numero = 0 soma = [] tamanho_lista = len(lista) while i < len(lista): j = i + 1 soma.clear() soma.append(lista[i]) while j < len(lista): if lista[j] < lista[i]: soma.append(lista[j]) # fiz isso para que se o sum da lista soma for maior que o maior numero da lista # ele já passa e muda o indice i do while, ou seja passa para o próximo número # de início if sum(soma) > maior_numero_lista: j = len(lista) + 1 else: if sum(soma) in lista: if len(soma) > maior_sequencia: maior_sequencia = len(soma) maior_numero = sum(soma) print("Maior sequencia = ",maior_sequencia) print(soma, "=" , maior_numero) print("Indice i =", i,"de", tamanho_lista, "- % analisados =", (i/tamanho_lista)*100,"%") print("------------------------------------") j += 1 i += 1 return maior_numero print("Resposta =", maior_numero_soma_seq(lista_primos))
Resposta (answer) - Selecione a linha abaixo para ver a resposta
997651
O script funciona da seguinte forma: crio uma lista com todos os números primos, depois vou analisando um a um com todas as somas possíveis (a soma tem que ser um número primo na lista).
Coloquei uns "print" para ver a evolução do processamento.
A medida que vai processando vai ficando cada vez mais lento, futuramente pretendo otimizar esse script.
Outras respostas postadas por outros usuários:
Usuário: dpinchbe
def primesieve(n): '''Sieve of Eratosthenes as suggested in Hans Riesel's Book''' ilist=[k for k in range(3,n+1,2)] #list of odds index=0 p=3 while p*p <= 2*((n-1)//2): #only looking at oddsmax(P): return [] if sum(P[k:k+length]) in P: return [P[k:k+length],sum(P[k:k+length])] return [] length=546 #I checked that 2+3+...+P_546 exceeds one million while not is_sum(length): length-=1 answer=is_sum(length) psum,firstp=answer[1],answer[0][0] print(psum," is the sum of ",length," consecutive primes") print("starting with ",firstp)
Usuário: skasch
def prm(n): f = [True] * n for i in [2] + list(range(3, int(sqrt(n)) + 1, 2)): if f[i]: f[2*i::i] = [False] * len(f[2*i::i]) return [i for i in [2] + list(range(3, n+1, 2)) if f[i]] N = 1000000 ps = prm(N) n = 0 ms = 0 while ms < N: ms += ps[n] n += 1 r = 0 for l in reversed(range(n)): i0 = 0 while sum(ps[i0:i0+l]) < N: if sum(ps[i0:i0+l]) in ps: r = sum(ps[i0:i0+l]) i0 += 1 if r != 0: break print(r)
Nenhum comentário:
Postar um comentário