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
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))
def F(plist): return pef.cprod([2*n+1 for n in plist])