コード例 #1
0
def pe202():
    """
     | \| \| \| \| \| \|   Expand triangle mirrors infinitely, then every 
     +--+--+--+--+--+--+-  possible path is a C-C line from bottomleft to
    C|\B|\A|\C|\B|\A|\C|\  somewhere upright and doesn't cross any vertex.
     | \| \| \| \| \| \|   
     +--+--+--+--+--+--+-  From the table can easity see that C-C lines are
    B|\A|\C|\B|\A|\C|\B|\  symmetric and lie on y = x + 3k. Without loss of
     | \| \| \| \| \| \|   generality, we just need to count all (a, b) with
     +--+--+--+--+--+--+-  a > b.
    A|\C|\B|\A|\C|\B|\A|\  
     | \| \| \| \| \| \|   Also, from (0, 0) to (a, b), the amount of cross
     +--+--+--+--+--+--+-  points with horizontal, vertical and diagonal
    C  B  A  C  B  A  C    lines is (a-1) + (b-1) + (a+b-1) = 2a + 2b - 3.
    
    Therefore to bounce N times, we need to find all (a, b) that:
        (1) a + b = (N + 3) / 2
        (2) gcd(a, b) = 1
        (3) a - b = 3k
    
    Recording to reference articles PE202, the number of solutions of (1), (2)
    and (3) is:
    
        sum m(d) * f(n/d) for all d satisfying d|n
    
    where m(x) if mobius function, f(x) = floor(x/2) - floor(x/3)
    """
    
    def f(x):
        return x / 2 - x / 3
    
    N = 12017639147
    N = (N + 3) / 2 # 6008819575
    
    # 6008819575 = 5*5 * 11 * 17 * 23 * 29 * 41 * 47
    pfactors = (5, 11, 17, 23, 29, 41, 47)
    count = f(N)
    for i in range(1, len(pfactors)+1):
        for pcomb in pec.combinations(pfactors, i):
            d = pef.cprod(pcomb)
            if i % 2:
                count -= f(N / d)
            else:
                count += f(N / d)
    
    # answer: 1209002624
    return count * 2
コード例 #2
0
def pe209():
    """
    Take input as integer in 0~63. Then it's equivalent to how many binary
    functions F(x) with 0 <= x <= 63 subjected to F(a) * F(b) = 0 for some
    a, b which b is determined by a.
    There are some cycles in the mapping. So we just need to find valid
    ways of each cycle, which becomes a easy combinatoric problem.
    """

    def valid_permutations(n):
        """
        Count valid permutations of chain with length n. Each element of chain 
        can only be 0 or 1. No consecutive 1s. Head and tail is regarded as
        consecutive too.
        Therefore it would be 0~floor(n/2) possible 1s.
        For a chain of A 0s and B 1s, there's C(A-1, B-1) chains with head of 1
        and C(A, B) chains with head of 0.
        """
        
        x = 1
        for i in range(1, n/2+1):
            x += pec.C(n-i-1, i-1) + pec.C(n-i, i)
        return x

    pairs = {}
    for n in range(64):
        s = bin(n)[2:]
        s = '0' * (6-len(s)) + s
        a, b, c = map(int, s[:3])
        s = s[1:] + str(a ^ (b & c))
        pairs[n] = int(s, 2)

    # There are 6 cycles in pairs, started with 0, 1, 3, 5, 9, 21
    starts, lchains = (0, 1, 3, 5, 9, 21), []
    for i in starts:
        z = set([i])
        n = pairs[i]
        while n > i:
            z.add(n)
            n = pairs[n]
        lchains.append(len(z))
    
    # answer: 15964587728784
    return pef.cprod(map(valid_permutations, lchains))
コード例 #3
0
 def F(plist):
     return pef.cprod([2*n+1 for n in plist])