Project Euler #50: Consecutive prime sum

  • + 0 comments

    This is my python solution for this question but only 5 testcases will be passed......

    import math
    
    prs = []
    prSum = []
    
    def mulmod(a, b, mdlo):
        if a <= 0xFFFFFFF and b <= 0xFFFFFFF:
            return (a * b) % mdlo
        result = 0
        factor = a % mdlo
        while b > 0:
            if b & 1:
                result += factor
                if result >= mdlo:
                    result %= mdlo
            factor <<= 1
            if factor >= mdlo:
                factor %= mdlo
            b >>= 1
        return result
    
    def powmod(base, expo, mdlo):
        result = 1
        while expo > 0:
            if expo & 1:
                result = mulmod(result, base, mdlo)
            base = mulmod(base, base, mdlo)
            expo >>= 1
        return result
    
    def isPrime(p):
        biPri = (1 << 2) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (1 << 13) | (1 << 17) | (1 << 19) | (1 << 23) | (1 << 29)
        if p < 31:
            return (biPri & (1 << p)) != 0
        if p % 2 == 0 or p % 3 == 0 or p % 5 == 0 or p % 7 == 0 or p % 11 == 0 or p % 13 == 0 or p % 17 == 0:
            return False
        if p < 17 * 19:
            return True
        tesAg1 = [377687, 0]
        tesAg2 = [31, 73, 0]
        tesAg3 = [2, 7, 61, 0]
        tesAg4 = [2, 13, 23, 1662803, 0]
        tesAg7 = [2, 325, 9375, 28178, 450775, 9780504, 1795265022, 0]
        tesAgst = tesAg7
        
        if p < 5329:
            tesAgst = tesAg1
        elif p < 9080191:
            tesAgst = tesAg2
        elif p < 4759123141:
            tesAgst = tesAg3
        elif p < 1122004669633:
            tesAgst = tesAg4
    
        d = p - 1
        d >>= 1
        shift = 0
        while (d & 1) == 0:
            shift += 1
            d >>= 1
        while tesAgst[0] != 0:
            x = powmod(tesAgst[0], d, p)
            if x == 1 or x == (p - 1):
                tesAgst = tesAgst[1:]
                continue
            mPrime = False
            for r in range(shift):
                x = powmod(x, 2, p)
                if x == 1:
                    return False
                if x == (p - 1):
                    mPrime = True
                    break
            if not mPrime:
                return False
            tesAgst = tesAgst[1:]
        return True
    
    def morePrimes(num):
        global prs, prSum
        if not prs:
            prs = [2, 3]
            prSum = [2]
        for i in range(prs[-1] + 2, num + 1, 2):
            isPrime = True
            for x in prs:
                if x * x > i:
                    break
                if i % x == 0:
                    isPrime = False
                    break
            if isPrime:
                prs.append(i)
        for i in range(len(prSum), len(prs)):
            prSum.append(prSum[-1] + prs[i])
    
    if __name__ == "__main__":
        ppb = int(math.pow(10, 4))
        morePrimes(ppb)
        T = int(input())
        while T > 0:
            N = int(math.pow(10, 6))
            N = int(input())
            best = 2
            maxLength = 0
            start = 0
            while prs[start] <= 131 and prs[start] <= N:
                subtract = 0
                if start > 0:
                    subtract = prSum[start - 1]
                pos = start + maxLength
                while prSum[pos] - subtract <= N:
                    pos += 1
                    if pos + 100 >= len(prs):
                        morePrimes(len(prs) + ppb)
                pos -= 1
                while (pos - start) > maxLength:
                    sum = prSum[pos] - subtract
                    if isPrime(sum):
                        maxLength = pos - start
                        best = sum
                        break
                    pos -= 1
                start += 1
            if best >= 2:
                maxLength += 1
            print(best, maxLength)
            T -= 1