Beispiel #1
0
from simple_profile import timed_call


def product(iterable):
    return reduce(lambda x, y: x * y, iterable, 1)


## naive solution
def solution1():
    return max(product(digits[i:i + 5]) for i in range(len(digits) - 5 + 1))


## a little better - get rid of errors
def solution2():
    max_product = 0
    i = 0
    while i < len(digits) - 5:
        if digits[i + 4] == 0:
            i += 9
            continue
        p = product(digits[i:i + 5])
        if p > max_product:
            max_product = p
        i += 1
    return max_product


## tests
if __name__ == '__main__':
    print timed_call(solution1)  ## 0.00236 secs
    print timed_call(solution2)  ## 0.00100 secs
Beispiel #2
0
                    ] if N - sum(solution) >= solution[1] else []
        else:
            return [
                solution + [n]
                for n in range(solution[0], (N - solution[0]) / 2 + 1)
            ]

    frontier = [[n] for n in range(1, N - 1)]  ## partial/complete solutions

    while frontier:
        solution = frontier.pop()
        if is_complete(solution):
            yield solution
        else:
            frontier += next(solution)


## simplication of backtracking sine the number of parts in solution is fixed
def solution2():
    N = 1000
    for a in range(1, int(ceil(N / 3)) + 1):
        for b in range(a, int(ceil((N - a) / 2)) + 1):
            c = N - a - b
            if a**2 + b**2 == c**2:
                yield (a, b, c)


## tests
if __name__ == '__main__':
    print timed_call(lambda: product(next(solution1())))  ## 0.05
    print timed_call(lambda: product(next(solution2())))  ##
Beispiel #3
0
            if prime_powers
            else 1)

def solution1():
    N = 500
    def triangles():
        t, i = 1, 1
        while True:
            yield t
            i += 1
            t += i
    
    return next(t for t in triangles() if num_factors(t) > N)

## tests
if __name__ == '__main__':
    ## test prime_factors
    assert [(n, prime_factors(n)) for n in range(1, 21)] == [
        (1, {}), (2, {2: 1}), (3, {3: 1}), (4, {2: 2}), 
        (5, {5: 1}), (6, {2: 1, 3: 1}), (7, {7: 1}), 
        (8, {2: 3}), (9, {3: 2}), (10, {2: 1, 5: 1}), 
        (11, {11: 1}), (12, {2: 2, 3: 1}), (13, {13: 1}), 
        (14, {2: 1, 7: 1}), (15, {3: 1, 5: 1}), (16, {2: 4}), 
        (17, {17: 1}), (18, {2: 1, 3: 2}), (19, {19: 1}), (20, {2: 2, 5: 1})]
    ## test num_factors
    assert [(n, num_factors(n)) for n in (1, 3, 6, 10, 15, 21, 28)] == [(1, 1), (3, 2), (6, 4), (10, 4), (15, 4), (21, 4), (28, 6)]
    ## test solution1
    t, r = timed_call(solution1)
    assert r == 76576500
    assert t < 7
    print 'all tests pass'
Beispiel #4
0
                                                              2: 1,
                                                              7: 1
                                                          }),
                                                          (15, {
                                                              3: 1,
                                                              5: 1
                                                          }), (16, {
                                                              2: 4
                                                          }), (17, {
                                                              17: 1
                                                          }),
                                                          (18, {
                                                              2: 1,
                                                              3: 2
                                                          }), (19, {
                                                              19: 1
                                                          }),
                                                          (20, {
                                                              2: 2,
                                                              5: 1
                                                          })]
 ## test num_factors
 assert [(n, num_factors(n))
         for n in (1, 3, 6, 10, 15, 21, 28)] == [(1, 1), (3, 2), (6, 4),
                                                 (10, 4), (15, 4), (21, 4),
                                                 (28, 6)]
 ## test solution1
 t, r = timed_call(solution1)
 assert r == 76576500
 assert t < 7
 print 'all tests pass'
Beispiel #5
0
Find the sum of all the primes below two million.
"""

## backenvlope 2x10**6 for O(n2)

from simple_profile import timed_call

def prime_sieve(hi):
    primes = [True for _ in range(hi)]
    primes[0] = primes[1] = False
    current = 2
    s = 0
    while current < hi:
        s += current
        i = 2
        while current * i < hi:
            primes[current * i] = False
            i += 1
        current += 1
        while current < hi and not primes[current]:
            current += 1
    return sum(p for p in range(hi) if primes[p])
    

## tests
if __name__ == '__main__':
    N = 2000000
    # test prime_sieve
    print timed_call(prime_sieve, N)  ## 2.08
Beispiel #6
0
## n has no factors in between 2 to i
## n is always >= i (for i * i <= n), so it is bigger than all other prime factors
## n is a factor of N
## => there is prime factor larger than n
################## Why the algorithm is correct ##############
## Because of the loop invariance
##############################################################
def largest_prime_factor(N):
    i, n = 2, N
    while i * i <= n:
        while n % i == 0 and n > i:
            n = n / i
            #largest_prime_factor.count += 1
        i += 1
    return n


## Solution 2
## find factors in O(sqrt(N)) and do the prime test
## find the max prime factor

# tests
if __name__ == '__main__':
    ## test the largest prime number
    largest_prime_factor.count = 0
    #assert largest_prime_factor(N) == 6857
    #print largest_prime_factor.count
    from simple_profile import timed_call
    #N = 688543
    print timed_call(largest_prime_factor, N)
Beispiel #7
0
    while nums:
        factor = min(nums)
        factors.append(factor)
        nums = filter(lambda x: x > 1, map(lambda x: x / factor if x % factor == 0 else x, nums))
    return factors


def solution1(N):
    return reduce(lambda x, y: x * y, factor_union(N), 1)


def solution2(N):
    def gcd(a, b):
        return b and gcd(b, a % b) or a

    def lcm(a, b):
        return a * b / gcd(a, b)

    n = 1
    for i in range(1, N + 1):
        n = lcm(n, i)
    return n


if __name__ == "__main__":
    ## test sieve for primes
    ## print sieve(20)
    t1, r1 = timed_call(solution1, 20)
    t2, r2 = timed_call(solution2, 20)
    print t1 < t2
Beispiel #8
0
    def next(solution):
        L = len(solution)
        if L == 3:
            return []
        elif L == 2:
            return [solution + [N-sum(solution)]] if N-sum(solution) >= solution[1] else []
        else:
            return [solution + [n] for n in range(solution[0], (N-solution[0])/2 + 1)]
    
    frontier = [[n] for n in range(1, N-1)] ## partial/complete solutions
    
    while frontier:
        solution = frontier.pop()
        if is_complete(solution):
            yield solution
        else:
            frontier += next(solution)
            
## simplication of backtracking sine the number of parts in solution is fixed
def solution2():
    N = 1000
    for a in range(1, int(ceil(N/3))+1):
        for b in range(a, int(ceil((N-a)/2))+1):
            c = N - a - b
            if a**2 + b**2 == c**2:
                yield (a, b, c)
            
## tests
if __name__ == '__main__':
    print timed_call(lambda: product(next(solution1()))) ## 0.05
    print timed_call(lambda: product(next(solution2()))) ## 
Beispiel #9
0
## use the fact that nums starts from 1
def factor_union(N):
    factors = []
    nums = range(2, N+1)
    while nums:
        factor = min(nums)
        factors.append(factor)
        nums = filter(lambda x: x > 1, 
                    map(lambda x: x/factor if x%factor == 0 else x,
                    nums))
    return factors
    
def solution1(N):
    return reduce(lambda x, y: x*y, factor_union(N), 1)
    
    
def solution2(N):
    def gcd(a, b): return b and gcd(b, a % b) or a
    def lcm(a, b): return a * b / gcd(a, b)
    n = 1
    for i in range(1, N+1):
        n = lcm(n, i)
    return n
    
if __name__ == '__main__':
    ## test sieve for primes
    ## print sieve(20)
    t1, r1 = timed_call(solution1, 20)
    t2, r2 = timed_call(solution2, 20)
    print t1 < t2
    
Beispiel #10
0
The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)**2 = 552 = 3025
Hence the difference between the sum of the squares of 
the first ten natural numbers and the square of the sum is 3025 - 385 = 2640.

Find the difference between the sum of the squares 
of the first one hundred natural numbers and the square of the sum.
"""

from itertools import combinations
from simple_profile import timed_call

N = 100

## solution 1
def solution1():
    return sum([
        2 * n1 * n2
        for (n1, n2) in combinations(range(1, N+1), 2)
        ])

## solution 2
def solution2():
    ns = xrange(1, N+1)
    s = sum(ns)
    return s * s - sum(n * n for n in ns)

print timed_call(solution1)
print timed_call(solution2)
Beispiel #11
0
def prime_generator():
    primes = [2]

    def is_prime(n):
        for p in primes:
            if p * p > n:
                return True
            if n % p == 0:
                return False

    while True:
        yield primes[-1]
        n = primes[-1] + 1
        while not is_prime(n):
            n += 1
        primes.append(n)


def solution1():
    N = 10001
    primes = prime_generator()
    for i in range(1, N):
        next(primes)
    return next(primes)


## tests
if __name__ == '__main__':
    print timed_call(solution1)  # 0.18 s
Beispiel #12
0
from simple_profile import timed_call

def product(iterable):
    return reduce(lambda x,y: x*y, iterable, 1)

## naive solution
def solution1():
    return max(
        product(digits[i:i+5]) 
        for i in range(len(digits) - 5 + 1)
    )
    
## a little better - get rid of errors
def solution2():
    max_product = 0
    i = 0 
    while i < len(digits) - 5:
        if digits[i+4] == 0:
            i += 9
            continue 
        p= product(digits[i:i+5])
        if p > max_product:
            max_product = p
        i += 1
    return max_product
    
## tests
if __name__ == '__main__':
    print timed_call(solution1) ## 0.00236 secs
    print timed_call(solution2) ## 0.00100 secs
Beispiel #13
0
## the performance depends on how sparse the primes
## are within the range

def prime_generator():
    primes = [2]
    def is_prime(n):
        for p in primes:
            if p * p > n:
                return True
            if n % p == 0:
                return False
    while True:
        yield primes[-1]
        n = primes[-1] + 1
        while not is_prime(n):
            n += 1
        primes.append(n)
     
     
def solution1():
    N = 10001
    primes = prime_generator()
    for i in range(1, N):
        next(primes)
    return next(primes)
       
## tests
if __name__ == '__main__':
    print timed_call(solution1) # 0.18 s