Im, изменяя неопределенное сито Eratoshenes от здесь, поэтому он использует факторизацию колес, чтобы пропускать больше композитов, чем его текущая форма просто проверки всех коэффициентов.
Ive разработал, как создать шаги, которые нужно предпринять, чтобы достичь всех пробелов вдоль колеса. Оттуда я решил, что могу просто заменить +2 на эти шаги колеса, но это заставило сито пропустить простые числа. Здесь код:
from itertools import count, cycle
def dvprm(end):
    "finds primes by trial division. returns a list"
    primes=[2]
    for i in range(3, end+1, 2):
        if all(map(lambda x:i%x, primes)):
            primes.append(i)
    return primes
def prod(seq, factor=1):
    "sequence -> product"
    for i in seq:factor*=i
    return factor
def wheelGaps(primes):
    """returns list of steps to each wheel gap
    that start from the last value in primes"""
    strtPt= primes.pop(-1)#where the wheel starts
    whlCirm= prod(primes)# wheel circumference
    #spokes are every number that are divisible by primes (composites)
    gaps=[]#locate where the non-spokes are (gaps)
    for i in xrange(strtPt, strtPt+whlCirm+1, 2):
        if not all(map(lambda x:i%x,primes)):continue#spoke 
        else: gaps.append(i)#non-spoke
    #find the steps needed to jump to each gap (beginning from the start of the wheel)
    steps=[]#last step returns to start of wheel
    for i,j in enumerate(gaps):
        if i==0:continue
        steps.append(j - gaps[i-1])
    return steps
def wheel_setup(num):
    "builds initial data for sieve"
    initPrms=dvprm(num)#initial primes from the "roughing" pump
    gaps = wheelGaps(initPrms[:])#get the gaps
    c= initPrms.pop(-1)#prime that starts the wheel
    return initPrms, gaps, c
def wheel_psieve(lvl=0, initData=None):
    '''postponed prime generator with wheels
    Refs:  http://stackoverflow.com/a/10733621
           http://stackoverflow.com/a/19391111'''
    whlSize=11#wheel size, 1 higher prime than
    # 5 gives 2- 3 wheel      11 gives 2- 7 wheel 
    # 7 gives 2- 5 wheel      13 gives 2-11 wheel
    #set to 0 for no wheel
    if lvl:#no need to rebuild the gaps, just pass them down the levels
        initPrms, gaps, c = initData
    else:#but if its the top level then build the gaps
        if whlSize>4:
            initPrms, gaps, c = wheel_setup(whlSize) 
        else:
            initPrms, gaps, c= dvprm(7), [2], 9
    #toss out the initial primes
    for p in initPrms:
        yield p
    cgaps=cycle(gaps)
    compost = {}#found composites to skip
    ps=wheel_psieve(lvl+1, (initPrms, gaps, c))
    p=next(ps)#advance lower level to appropriate square
    while p*p < c:
        p=next(ps)
    psq=p*p
    while True:
        step1 = next(cgaps)#step to next value
        step2=compost.pop(c, 0)#step to next multiple
        if not step2:
            #see references for details
            if c < psq:
                yield c
                c += step1
                continue
            else:
                step2=2*p
                p=next(ps)
                psq=p*p
        d = c + step2
        while d in compost:
            d+= step2
        compost[d]= step2
        c += step1
Я использую это, чтобы проверить это:
def test(num=100):
    found=[]
    for i,p in enumerate(wheel_psieve(), 1):
        if i>num:break
        found.append(p)
    print sum(found)
    return found
Когда я устанавливаю размер колеса равным 0, я получаю правильную сумму 24133 для первых 100 простых чисел, но когда я использую любой другой размер колеса, я получаю недостающие простые числа, неправильные суммы и композиты. Даже 2-3 колесо (которое использует чередующиеся шаги 2 и 4) делает пропущенные пропуски сита. Что я делаю неправильно?
