Toplamları Asal olan ardışık Asallar

Direk örnekten anlatayım 41 = 2 + 3 + 5 + 7 + 11 + 13
41 ardışık 6 tane asalın toplamı şeklinde yazılabiliyor.
üç basamaklı en uzun zincire sahip asal sayı 953 tür ve zincir uzunluğu 21 dir.
Buna göre 1 milyondan küçük en uzun zincire sahip asal hangisidir?

1 Beğeni

Ben şöyle bir şey düşündüm Fakat sorunum şu benim zincir hep eklemeli devam ediyor ve mesela 953 sayısını bulamıyor.nasıl bir yol izleyebilirim ?

import sympy
sayı=0
sayaç=0
liste=set()
for i in range(3900): #Burada listeyi inceledim 3900 yeterli geldiği için daha ileri gitmedim
    if sympy.isprime(i):
        sayı+=i
        sayaç += 1
    if sympy.isprime(sayı):
        liste.add((sayı,sayaç))

print(max(sorted(liste)))

Zincirin 2 den mi başlaması gerekiyor?

hayır sıkıntımda o noktada zaten

sıkıntıyı çözdüm ama farklı yollarıda görmek isterim siz nasıl yaklaşıcaksınız acaba

import sympy
asallar=[]
for i in range(5000):
    if sympy.isprime(i):
        asallar.append(i)
        for j in range(len(asallar)):
            zincir=asallar[j:]
            if sympy.isprime(sum(zincir))==True:
                if len(zincir)>540 and sum(zincir)<10**6: # Burada 540 dan büyük almamın sebebi diğer kodla 536 bulmamdır.
                    print(sum(zincir), len(zincir))

sqlite3 modülü yardımıyla 1 milyona kadar olan asal sayıları barındıran bir veri tabanı oluşturdum. Veritabanı dosyasının adı “AsalSayılar1m.mbe”. Aşağıdaki kodlarlada sonucu buldum.

import numpy as np
import sqlite3
with sqlite3.connect("AsalSayılar1m.mbe") as vt1:
    im1 = vt1.cursor()
    liste = []
    im1.execute("""select * from asal_sayilar""")
    while True:
        i = im1.fetchone()[0]
        if i != 999983:
            liste.append(i)
        else:
            liste.append(i)
            break
    ndizi = np.array(liste)
def zincirleme_bulucu(dizi,y,zincir):
    for x in dizi:
        y += x
        zincir +=1
        if y > 1000000:
            break
        if y in ndizi:
            try:
                if z != y:
                    z = y
                    istenen_son = z
                    istenen_zincir = zincir
            except NameError:
                z=y
    liste2.append([istenen_son, istenen_zincir])
    del istenen_son
    del istenen_zincir
liste2 = []
s = 0
while ndizi[s]!=ndizi[-1]:
    zincirleme_bulucu(ndizi[s:],0,0)
    s+=1
    if liste2[-1][1]<=400:
        break
c = 0
for m in liste2:
    if c<m[1]:
        c=m[1]
for n in liste2:
    if c==n[1]:
        print("Asal sayı : "+str(int(n[0]))+"      Zincir sayısı : "+str(int(n[1])))
        break

Kodlar çalıştığında birkaç saniye sonra şu çıktıyı verir.
Asal sayı : 997651 Zincir sayısı : 543
İnşallah doğru bulmuşumdur.

2 Beğeni

Güzel yapmışsınız ama pek gerekli değil, sympy.sieve nesnesinin extend metodu kullanılabilir:

Bir de böyle basit bir iş için Sqlite kullanmaya gerek yok.

@EkremDincel sympy kütüphanesini bilmiyordum. Yorumunuz için teşekkürler. normal liste ile dahada uzun işlem yaptığı için veritabanı kullanmayı tercih ettim.

Asal jeneratoru:

import sympy

def primes():
    n = 1
    while True:
        yield sympy.prime(n)
        n += 1

(sympy’de yok mu?)

Suradaki inits fonksiyonunun tembel/jenerator versiyonu:

def inits(it):
    head = []
    while True:
        e = next(it)
        yield head + [e]
        head += [e]

Asal zinciri jeneratoru:

import itertools

def ranges_less_than(gen, sum_):
    g1, g2 = itertools.tee(gen)
    yield from itertools.takewhile(lambda ps: sum(ps) <= sum_, inits(g1))
    try:
        n = next(g2)
    except StopIteration:
        return
    if n > sum_:
        return
    yield from ranges_less_than(g2, sum_)

Toplami asal < 999 olan cok halkali zincirler:

chains = filter(lambda ns_len_sum: ns_len_sum[1] > 1 and sympy.isprime(ns_len_sum[2]), map(lambda ns: (ns, len(ns), sum(ns)), ranges_less_than(primes(), 999)))

En uzun zincir:

print(sorted(chains, key=lambda n_l_s: n_l_s[1], reverse=True)[0])

([7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89], 21, 953)

Challenge:

Toplami sum_'dan kucuk olan butun gen zincirlerini ureten yukaridaki ranges_less_than fonksiyonunun butun gen zincirlerini ureten versiyonunu yazin.

2 Beğeni

Generator şeklinde var mı bilmiyorum ama liste olarak elde edebiliyoruz:


Benim oradaki kastım sizin de bir dosyaya yazabileceğinizdi.

Buradaki primerange de aynı işi görürmüş aslında

1 Beğeni