Commit bd756ea1 by Nayuki Minase

### P89, P91, P92, P97, P102, P104, P112, P113, P114, P115, P116, P117, P218: Added Python solutions.

parent 87dee051
 ... ... @@ -88,6 +88,19 @@ ANSWERS = { 80: "40886", 81: "427337", 85: "2772", 89: "743", 91: "14234", 92: "8581146", 97: "8739992577", 102: "228", 104: "329468", 112: "1587000", 113: "51161058134250", 114: "16475640049", 115: "168", 116: "20492570929", 117: "100808458960497", 218: "0", } ... ...
python/p089.py 0 → 100644
This diff is collapsed.
python/p091.py 0 → 100644
 # # Solution to Project Euler problem 91 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # def compute(): LIMIT = 51 ans = 0 for x1 in range(LIMIT): for y1 in range(LIMIT): for x2 in range(LIMIT): for y2 in range(LIMIT): # For uniqueness, ensure that (x1,y1) has a larger angle than (x2,y2) if y2 * x1 < y1 * x2 and is_right_triangle(x1, y1, x2, y2): ans += 1 return str(ans) # Tests whether {(0,0), (x1,y1), (x2,y2)} forms a right triangle. def is_right_triangle(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 a = x1 * x1 + y1 * y1 b = x2 * x2 + y2 * y2 c = dx * dx + dy * dy return a + b == c or b + c == a or c + a == b if __name__ == "__main__": print(compute())
python/p092.py 0 → 100644
 # # Solution to Project Euler problem 92 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # def compute(): ans = 0 for i in range(1, 10000000): while i != 1 and i != 89: i = square_digit_sum(i) if i == 89: ans += 1 return str(ans) def square_digit_sum(n): result = 0 while n > 0: x = n % 10 result += x * x n //= 10 return result if __name__ == "__main__": print(compute())
python/p097.py 0 → 100644
 # # Solution to Project Euler problem 97 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # def compute(): MOD = 10**10 ans = (28433 * pow(2, 7830457, MOD) + 1) % MOD return str(ans) if __name__ == "__main__": print(compute())
python/p102.py 0 → 100644
This diff is collapsed.
python/p104.py 0 → 100644
 # # Solution to Project Euler problem 104 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # def compute(): MOD = 10**9 a = 0 b = 1 i = 0 while True: if "".join(sorted(str(a))) == "123456789" and "".join(sorted(str(fibonacci(i)[0])[ : 9])) == "123456789": return str(i) a, b = b, (a + b) % MOD i += 1 return str(ans) # Returns the tuple (F(n), F(n+1)). def fibonacci(n): if n == 0: return (0, 1) else: a, b = fibonacci(n // 2) c = a * (b * 2 - a) d = a * a + b * b if n % 2 == 0: return (c, d) else: return (d, c + d) if __name__ == "__main__": print(compute())
python/p112.py 0 → 100644
 # # Solution to Project Euler problem 112 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # import itertools def compute(): count = 0 for i in itertools.count(1): s = str(i) t = "".join(sorted(s)) if s != t and s[::-1] != t: count += 1 # i is bouncy if count * 100 == 99 * i: return str(i) if __name__ == "__main__": print(compute())
python/p113.py 0 → 100644
 # # Solution to Project Euler problem 113 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # import eulerlib # Let n be the number of digits. To count the number of increasing or decreasing numbers using combinatorics, # let's view each number as a sequence of digit readout slots and operations. For example, suppose n=5 and # we examine the increasing number 23667. We can express it as the sequence "+ + # + # + + + # # + # + +", # where # is a digit and + means increment. This way of thinking will be useful, as we will see. # # For the set of increasing numbers, each number has n readout slots and 9 increments, positioned arbitrarily. # Using this construction, the number is guaranteed to be increasing. Note that leading zeros can be produced. # Conversely, for each increasing number, we can generate a (unique) sequence of slots and increments that represents it # (putting all unused increments after the rightmost digit). Hence there are n+9 objects to arrange in sequence, # so there are binomial(n + 9, 9) ways to arrange them. Finally we subtract 1 because 0 can be formed with this scheme, # which must be excluded from the set of increasing numbers. # # For the set of decreasing numbers, each number has n readout slots and 10 operations. Of the 10 operations, # the leading one must be "increment to 9", and the rest must be decrements. Similar to the increasing case, # each sequence of slots and decrements produces a decreasing number, and conversely each decreasing number # corresponds to a unique sequence of slots and decrements. However, 0 can be formed in n+1 ways, by concentrating # all 10 operations between some pair of slots, e.g. "+9 -9 # # # #", "# +9 -9 # # #", ..., "# # # # +9 -9". # # There are 9n "flat" numbers, for example: 1, 2, ..., 9; 11, 22, ..., 99; 111, 222, ..., 999; ... (note that 0 is excluded). # Since they are double-counted in the increasing and decreasing numbers, we subtract the size of this set. # # In conclusion, the number of non-bouncy numbers is (binomial(n+9,9) - 1) + (binomial(n+10,10) - (n+1)) - 9n. # # (Technically, in the problem statement and this solution, "increasing" actually means "nondecreasing" and "decreasing" means "nonincreasing".) def compute(): DIGITS = 100 increasing = binomial(DIGITS + 9, 9) - 1 decreasing = binomial(DIGITS + 10, 10) - (DIGITS + 1) flat = DIGITS * 9 ans = increasing + decreasing - flat return str(ans) def binomial(n, k): return eulerlib.factorial(n) // (eulerlib.factorial(k) * eulerlib.factorial(n - k)) if __name__ == "__main__": print(compute())
python/p114.py 0 → 100644
 # # Solution to Project Euler problem 114 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # # How many ways can a row n units long be filled? Denote this quantity as ways[n]. # Compute n = 0, 1, 2 manually as base cases. # # Now assume n >= 3. Look at the leftmost item and sum up the possibilities. # - If the item is a black square, then the rest of the row is allowed # to be anything of length n-1. Add ways[n-1]. # - If the item is a red block with length k where k >= 3, then: # - If k = n, then the whole row is filled by this red block. Add 1. # - Otherwise k < n, this red block is followed by a black square, then followed # by anything of length n-k-1. So add ways[n-4] + ways[n-5] + ... + ways[0]. def compute(): # Dynamic programming LENGTH = 50 ways = [0] * (LENGTH + 1) for n in range(len(ways)): if n < 3: ways[n] = 1 else: ways[n] = ways[n - 1] + sum(ways[ : n - 3]) + 1 return str(ways[-1]) if __name__ == "__main__": print(compute())
python/p115.py 0 → 100644
 # # Solution to Project Euler problem 115 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # import itertools # How many ways can a row n units long be filled, where red blocks are # at least m units long? Denote this quantity as ways[n]. # Compute n = 0 manually as a base case. # # Now assume n >= 1. Look at the leftmost item and sum up the possibilities. # - If the item is a black square, then the rest of the row is allowed # to be anything of length n-1. Add ways[n-1]. # - If the item is a red block with length k where k >= m, then: # - If k = n, then the whole row is filled by this red block. Add 1. # - Otherwise k < n, this red block is followed by a black square, then followed # by anything of length n-k-1. So add ways[n-m-1] + ways[n-m-2] + ... + ways[0]. def compute(): # Dynamic programming M = 50 ways = [1] for n in itertools.count(1): s = ways[n - 1] + sum(ways[ : max(n - M, 0)]) if n >= M: s += 1 ways.append(s) if s > 1000000: return str(n) if __name__ == "__main__": print(compute())
python/p116.py 0 → 100644
 # # Solution to Project Euler problem 116 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # def compute(): LENGTH = 50 return str(sum(count_ways(LENGTH, i) for i in range(2, 5))) # How many ways can a row n units long be filled with black squares 1 unit long # and colored tiles m units long? Denote this quantity as ways[n]. # Compute n = 0 manually as a base case. # # Now assume n >= 1. Look at the leftmost item and sum up the possibilities. # - If the item is a black square, then the rest of the row # is allowed to be anything of length n-1. Add ways[n-1]. # - If the item is a colored tile of length m where m <= n, then the # rest of the row can be anything of length n-m. Add ways[n-m]. # # At the end, return ways[length]-1 to exclude the case where the row is all black squares. def count_ways(length, m): # Dynamic programming ways = [0] * (length + 1) ways[0] = 1 for n in range(1, len(ways)): ways[n] += ways[n - 1] if n >= m: ways[n] += ways[n - m] return ways[-1] - 1 if __name__ == "__main__": print(compute())
python/p117.py 0 → 100644
 # # Solution to Project Euler problem 117 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # # How many ways can a row n units long be filled with: # - Black squares 1 unit long # - Red tiles 2 units long # - Green tiles 3 units long # - Blue tiles 4 units long # Denote this quantity as ways[n]. # # Compute n = 0 manually as a base case. # Now assume n >= 1. Look at the leftmost item and sum up the possibilities. # - Black square (n>=1): Rest of the row can be anything of length n-1. Add ways[n-1]. # - Red tile (n>=2): Rest of the row can be anything of length n-2. Add ways[n-2]. # - Green tile (n>=3): Rest of the row can be anything of length n-3. Add ways[n-3]. # - Blue tile (n>=4): Rest of the row can be anything of length n-4. Add ways[n-4]. def compute(): # Dynamic programming LENGTH = 50 ways = [0] * (LENGTH + 1) ways[0] = 1 for n in range(1, len(ways)): ways[n] += sum(ways[max(n - 4, 0) : n]) return str(ways[-1]) if __name__ == "__main__": print(compute())
python/p218.py 0 → 100644
 # # Solution to Project Euler problem 218 # by Project Nayuki # # http://www.nayuki.io/page/project-euler-solutions # https://github.com/nayuki/Project-Euler-solutions # # == Primitive Pythagorean triples == # # Each valid pair generates a PPT: # # For each pair of positive integers (s,t) such that s > t, they are coprime, and one of them # is odd and one of them is even: Let a = s^2 - t^2 (odd), b = 2st (even), and c = s^2 + t^2 (odd). # Then (a,b,c) is a primitive Pythagorean triple (PPT). # # Proof: The fact that a^2 + b^2 = c^2 can be readily verified. Now for the sake of contradiction, # suppose some prime p divides each of {a,b,c} (which would make the Pythagorean triple non-primitive). # Since p divides b = 2st and p is prime, p must divide at least one of {2,s,t}. a is odd, so 2 doesn't # divide a, so p != 2. Hence p > 2, and p must divide at least one of {s,t}. p divides c = s^2 + t^2. # WLOG if p divides s, then p divides the difference c - s^2 = t^2, thus p divides t. # Therefore p divides {s,t}, contradicting that {s,t} are coprime. # # Each PPT can be generated from some valid pair: # # Conversely, for each PPT (a,b,c) there exists an (s,t), satisfying the restrictions above, # that generates it using the relations above. # # Proof: WLOG assume that a is odd (otherwise swap the roles of a and b). Knowing that a^2 + b^2 = c^2 # and b is even, rearrange it to get (b/2)^2 = (c^2 - a^2)/4 = [(c-a)/2][(c+a)/2]. The claim is that # (c-a)/2 and (c+a)/2 are both perfect squares. For any prime p, if it divides both (c-a)/2 and (c+a)/2, # then it divides the sum (which is c) and the difference (which is a), so it would also divide c^2 - a^2 = b^2, # contradicting the primitiveness. Thus each prime power (i.e. p^k) in the factorization of (b/2)^2 appears # in either the factor (c-a)/2 or the factor (c+a)/2. Since (b/2)^2 is a perfect square, each prime power # in it is a perfect square, and it would contribute to either (c-a)/2 or (c+a)/2, making both of them # perfect squares as well. # # With this setup, let s = sqrt((c+a)/2) and t = sqrt((c-a)/2), which are both positive integers. # It's easy to verify that a = s^2 - t^2, b = 2st, and c = s^2 + t^2. Clearly s > t, since a is added in s # while a is subtracted in t. {s,t} cannot both be even or both be odd, otherwise 2 divides all of {a,b,c}, # contradicting primitiveness. {s,t} must be coprime, otherwise some p divides {s,t}, so p^2 divides s^2 = (c+a)/2 # and p^2 divides t^2 = (c-a)^2, which contradicts {a,c} being coprime using the argument above. # # # == Perfect triangles == # # A perfect right-angled triangle (a,b,c) has c = r^2 for some integer r. We use the PPT theorem converse # to find (s,t). The area of the triangle (a,b,c) is ab/2 = (s^2 - t^2)(2st)/2 = st(s^2 - t^2). # Curiously, we have c = s^2 + t^2 = r^2, which means (s,t,r) is itself a Pythagorean triple, and in fact # a primitive one because (s,t) are coprime. Use the PPT theorem converse on (s,t,r) (or (t,s,r), depending on # which of s or t is odd) to find (u,v), i.e. s = u^2 - v^2, t = 2uv, and r = u^2 + v^2. # So the area is also expressible as (u^2 - v^2)(2uv)[(u^2 - v^2)^2 - (2uv)^2]. # # The area is divisible by 6 and 28 (super-perfectness) iff it is divisible by lcm(6, 28) = 84 # = 3 * 4 * 7 (coprime factorization) iff it is divisible by 3, 4, and 7. # Now, the area is divisible by 4 because in the factor 2uv, either u or v is even. # The area is divisible by 3 because st is a factor in one of the area formulas, and with (s,t,r) being # a Pythagorean triple, at least one of {s,t} must be 0 mod 3 (see footnote 0). # Similarly, since (s,t,r) is a Pythagorean triple, 7 divides at least one of {s,t} (so 7 divides # the area factor of st), or s^2 = t^2 mod 7 (so 7 divides the area factor s^2 - t^2) (see footnote 1). # # In conclusion, every perfect right-angled triangle is also super-perfect. # There is no perfect triangle that isn't super-perfect. # # Footnote 0: This can be proven by brute force over the 3^3 cases of values of s,t,r mod 3. # Or alternatively: If s or t is 0 mod 3, then we're done. Otherwise, s is either 1 or 2 mod 3, # and t is either 1 or 2 mod 3. s^2 = 1 mod 3, and t^2 = 1 mod 3. s^2 + t^2 = 2 = r^2 mod 3, # but no r can satisfy r^2 = 2 mod 3. So this "otherwise" case is impossible. # # Footnote 1: This can also be proven by brute force over all 7^3 cases of values of s,t,r mod 7. # Or alternatively: If s or t is 0 mod 7, then we're done. Otherwise, notice that for k != 0 mod 7, # we have that k^2 mod 7 is in the set {1,2,4} (quadratic residues). If s^2 != t^2 mod 7, # then their sum mod 7 is not a residue, so r^2 != s^2 + t^2. Therefore it must be that s^2 = t^2 mod 7 # (e.g. s = 3 mod 7, t = 4, r = 2 mod 7). def compute(): return "0" if __name__ == "__main__": print(compute())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!