diff --git a/.problem-54.py.swp b/.problem-54.py.swp new file mode 100644 index 0000000..c465712 Binary files /dev/null and b/.problem-54.py.swp differ diff --git a/primes.py b/primes.py new file mode 100644 index 0000000..3095b3a --- /dev/null +++ b/primes.py @@ -0,0 +1,54 @@ + +def sieve(limit): + '''https://stackoverflow.com/a/3941967 + ''' + a = [True] * limit # Initialize the primality list + a[0] = a[1] = False + + for (i, isprime) in enumerate(a): + if isprime: + yield i + for n in range(i*i, limit, i): # Mark factors non-prime + a[n] = False + + +def is_prime(n): + '''Returns True if n is prime. + https://stackoverflow.com/a/18833845''' + if n == 1: + return False + if n == 2: + return True + if n == 3: + return True + if n % 2 == 0: + return False + if n % 3 == 0: + return False + + i = 5 + w = 2 + + while i * i <= n: + if n % i == 0: + return False + i += w + w = 6 - w + + return True + + +def prime_factors(n): + '''https://stackoverflow.com/a/22808285 + ''' + i = 2 + factors = [] + while i * i <= n: + if n % i: + i += 1 + else: + n //= i + factors.append(i) + if n > 1: + factors.append(n) + return factors diff --git a/problem-22.py b/problem-22.py new file mode 100644 index 0000000..814aab7 --- /dev/null +++ b/problem-22.py @@ -0,0 +1,24 @@ + +import requests +import string + +if __name__ == '__main__': + url = 'https://projecteuler.net/project/resources/p022_names.txt' + text = requests.get(url).text.replace('"', '') + names = sorted(text.split(',')) + letter_values = dict(zip(string.ascii_uppercase, list(range(1, 27)))) + + total = 0 + for idx, name in enumerate(names): + name_total = 0 + for letter in name: + name_total += letter_values[letter] + if name == 'COLIN': + print(name, idx+1, name_total, (idx+1) * name_total) + total += (idx+1) * name_total + print(total) + + + + + diff --git a/problem-26.py b/problem-26.py new file mode 100644 index 0000000..eb42107 --- /dev/null +++ b/problem-26.py @@ -0,0 +1,14 @@ +tests = [(x, 1/x) for x in range(2,11)] + +def check_repeats(number): + number = str(number) + longest = '' + for i in range(1, len(number)+1): + sample = number[:i] + while number[:i] == + + +if __name__ == '__main__': + for test in tests: + result = check_repeats(str(test[1])[2:]) + print('Test %s = %s, %s\n'.format(test[0], test[1], result)) diff --git a/problem-27.py b/problem-27.py new file mode 100644 index 0000000..4b8176f --- /dev/null +++ b/problem-27.py @@ -0,0 +1,37 @@ +import math +import itertools + + +def is_prime(n): + if n % 2 == 0 and n > 2 or n < 0: + return False + return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2)) + + +def form(n, a, b): + result = n**2 + a*n + b + return n**2 + a*n + b + + +def get_sequence(pair): + i = 0 + while True: + if not is_prime(form(i, pair[0], pair[1])): + return list(range(i)) + i += 1 + + +if __name__ == '__main__': + a = list(range(-1000, 1000)) + b = list(range(-1000, 1001)) + pairs = list(itertools.product(a, b)) + print('number of pairs:', len(pairs)) + + longest = [pairs[0], [0]] + for pair in pairs: + seq = get_sequence(pair) + if len(seq) > len(longest[1]): + longest = (pair, seq) + print(longest) + + diff --git a/problem-28.py b/problem-28.py new file mode 100644 index 0000000..3c8c941 --- /dev/null +++ b/problem-28.py @@ -0,0 +1,12 @@ +nums = [1] +spiral = 1 +while spiral < 1001: + spiral += 2 + circ = list(range(nums[-1] + 1, nums[-1] + (spiral**2))) + nums.append(circ[(spiral-1)*1-1]) + nums.append(circ[(spiral-1)*2-1]) + nums.append(circ[(spiral-1)*3-1]) + nums.append(circ[(spiral-1)*4-1]) + +print(spiral) +print(sum(nums)) diff --git a/problem-29.py b/problem-29.py new file mode 100644 index 0000000..6508e6e --- /dev/null +++ b/problem-29.py @@ -0,0 +1,9 @@ + +results = [] +if __name__ == '__main__': + for a in range(2, 101): + for b in range(2, 101): + results.append(a**b) + +print(len(set(results))) + diff --git a/problem-30.py b/problem-30.py new file mode 100644 index 0000000..4561200 --- /dev/null +++ b/problem-30.py @@ -0,0 +1,14 @@ + +MAX_NUM = 1000000 + +results = [] + +for i in range(2, MAX_NUM+1): + digits = list(str(i)) + total = sum([int(x)**5 for x in digits]) + if total == i: + results.append(i) + +print(results) +print(sum(results)) +print(len(results)) diff --git a/problem-31.py b/problem-31.py new file mode 100644 index 0000000..eb4ba59 --- /dev/null +++ b/problem-31.py @@ -0,0 +1,38 @@ + +import itertools + +pence = list(range(201)) +two_pence = list(range(101)) +five_pence = list(range(41)) +ten_pence = list(range(21)) +twenty_pence = list(range(11)) +fifty_pence = list(range(5)) +pound = [0, 1, 2] +two_pound = [0, 1] + +results = [] +combos = itertools.product( + pence, + two_pence, + five_pence, + ten_pence, + twenty_pence, + fifty_pence, + pound, +# two_pound + ) + +for combo in combos: + if combo[0] \ + + combo[1] * 2 \ + + combo[2] * 5 \ + + combo[3] * 10 \ + + combo[4] * 20 \ + + combo[5] * 50 \ + + combo[6] * 100 == 200: + results.append(combo) + +results.append((0, 0, 0, 0, 0, 0)) # representing 1 pound coin + +print(results) +print(len(results)) diff --git a/problem-32.py b/problem-32.py new file mode 100644 index 0000000..d42c37e --- /dev/null +++ b/problem-32.py @@ -0,0 +1,17 @@ +import itertools +from pprint import pprint + +MAX_NUM = int(999999999**0.5) + 1 + +results = [] + +for i in range(MAX_NUM): + for j in range(MAX_NUM): + num = i * j + if ''.join(sorted(str(i) + str(j) + str(num))) == '123456789': + results.append((i, j, num)) + +pprint(results) +print(len(results)) +print(sum(set(x[2] for x in results))) + diff --git a/problem-33.py b/problem-33.py new file mode 100644 index 0000000..aaab62c --- /dev/null +++ b/problem-33.py @@ -0,0 +1,25 @@ + +from pprint import pprint + +results = [] +for numerator in range(10, 100): + if str(numerator)[-1] == '0': + continue + for denominator in range(10, 100): + if str(denominator)[-1] == '0': + continue + if str(numerator)[0] == str(numerator)[1] \ + and str(denominator)[0] == str(denominator)[1]: + continue + frac = numerator / denominator + if frac < 1: + short_numerator = int(str(numerator)[0]) + short_denominator = int(str(denominator)[1]) + short_frac = short_numerator / short_denominator + if numerator == 49 and denominator == 98: + pprint(locals()) + if frac == short_frac: + results.append((numerator, denominator)) + +pprint(results) + diff --git a/problem-34.py b/problem-34.py new file mode 100644 index 0000000..cc60ca8 --- /dev/null +++ b/problem-34.py @@ -0,0 +1,18 @@ + +MAX_NUM = 100000 + +def fact(n): + result = 1 + for i in range(2, n+1): + result *= i + return result + +if __name__ == '__main__': + results = [] + for i in range(3, MAX_NUM): + digits = list(str(i)) + if i == sum([fact(int(j)) for j in digits]): + results.append(i) + +print(results) +print(sum(results)) diff --git a/problem-35.py b/problem-35.py new file mode 100644 index 0000000..806f7a1 --- /dev/null +++ b/problem-35.py @@ -0,0 +1,52 @@ + +MAX_NUM = 1000000 + +def is_prime(n): + """Returns True if n is prime.""" + if n == 1: + return False + if n == 2: + return True + if n == 3: + return True + if n % 2 == 0: + return False + if n % 3 == 0: + return False + + i = 5 + w = 2 + + while i * i <= n: + if n % i == 0: + return False + i += w + w = 6 - w + + return True + + +if __name__ == '__main__': + results = [] + for i in range(MAX_NUM): + if not is_prime(i): + continue + j = str(i) + if len(j) == 1: + if is_prime(i): + results.append(i) + continue + if len(j) == 2: + if is_prime(i) and is_prime(int(j[1] + j[0])): + results.append(i) + continue + for rotation in range(len(j)): + prime = True + j = j[1] + j[2:] + j[0] + if not is_prime(int(j)): + prime = False + break + if prime is True: results.append(i) + + print(results) + print(len(results)) diff --git a/problem-36.py b/problem-36.py new file mode 100644 index 0000000..17627d6 --- /dev/null +++ b/problem-36.py @@ -0,0 +1,13 @@ + +MAX_NUM = 1000000 + +if __name__ == '__main__': + results = [] + for i in range(MAX_NUM): + rev = int(str(i)[::-1]) + binary_i = bin(i)[2:] + rev_binary_i = binary_i[::-1] + if i == rev and binary_i == rev_binary_i: + results.append(i) + print(results) + print(sum(results)) diff --git a/problem-37.py b/problem-37.py new file mode 100644 index 0000000..1b5f4ea --- /dev/null +++ b/problem-37.py @@ -0,0 +1,55 @@ + +NUM_PRIMES = 11 +START_NUM = 9 + + +def is_prime(n): + """Returns True if n is prime.""" + if n == 1: + return False + if n == 2: + return True + if n == 3: + return True + if n % 2 == 0: + return False + if n % 3 == 0: + return False + + i = 5 + w = 2 + + while i * i <= n: + if n % i == 0: + return False + i += w + w = 6 - w + + return True + + +def truncatable_prime(i): + j = i + for _ in range(len(j)): + if not is_prime(int(j)): + return False + j = j[1:] + j = i + for _ in range(len(j)): + if not is_prime(int(j)): + return False + j = j[:-1] + return True + + +if __name__ == '__main__': + results = [] + i = START_NUM + while len(results) != NUM_PRIMES: + i += 1 + if truncatable_prime(str(i)): + results.append(i) + + print(results) + print(sum(results)) + diff --git a/problem-39.py b/problem-39.py new file mode 100644 index 0000000..f2ac198 --- /dev/null +++ b/problem-39.py @@ -0,0 +1,27 @@ + +from pprint import pprint + +MAX_NUM = 1000 + +if __name__ == '__main__': + As = list(range(1, MAX_NUM)) + results = [] + totals = {} + + for a in As: + for b in range(a, MAX_NUM): + if a > b: + continue + c = (a**2 + b**2) ** 0.5 + if c % 1 != 0: + continue + total = a + b + int(c) + if total > MAX_NUM: + continue + results.append((a, b, int(c), total)) + if total in totals: + totals[total] += 1 + else: + totals[total] = 1 + + print(max(totals, key=totals.get)) diff --git a/problem-40.py b/problem-40.py new file mode 100644 index 0000000..4e0d068 --- /dev/null +++ b/problem-40.py @@ -0,0 +1,11 @@ + +from functools import reduce + +if __name__ == '__main__': + digits = [1, 10, 100, 1000, 10000, 100000, 1000000] + number = '' + for i in range(digits[-1]): + number += str(i) + results = [int(number[x]) for x in digits] + result = reduce(lambda x, y: x * y, results, 1) + print(result) diff --git a/problem-41.py b/problem-41.py new file mode 100644 index 0000000..6940ce5 --- /dev/null +++ b/problem-41.py @@ -0,0 +1,25 @@ + +MAX_NUM = 987654321 + +def sieve_of_eratosthenes(limit): + a = [True] * limit # Initialize the primality list + a[0] = a[1] = False + + for (i, isprime) in enumerate(a): + if isprime: + yield i + for n in range(i*i, limit, i): # Mark factors non-prime + a[n] = False + + +if __name__ == '__main__': + results = [] + digits = '123456789' + primes = sieve_of_eratosthenes(MAX_NUM) + for prime in primes: + if ''.join(sorted(str(prime))) == digits[:len(str(prime))]: + results.append(prime) + + print(results) + + diff --git a/problem-42.py b/problem-42.py new file mode 100644 index 0000000..2c5d531 --- /dev/null +++ b/problem-42.py @@ -0,0 +1,27 @@ +import string +import requests + +MAX_NUM = 10000 +letter_values = dict(zip(string.ascii_uppercase, list(range(1, 27)))) +triangle_numbers = [0.5*n*(n+1) for n in range(MAX_NUM+1)] + +def value(word): + value = 0 + for letter in word: + value += letter_values[letter] + return value + + +if __name__ == '__main__': + data_url = 'https://projecteuler.net/project/resources/p042_words.txt' + text = requests.get(data_url).text.replace('"', '') + words = text.split(',') + + results = [] + for word in words: + if value(word) in triangle_numbers: + results.append(word) + print(results) + print(len(results)) + + diff --git a/problem-43.py b/problem-43.py new file mode 100644 index 0000000..a337f3f --- /dev/null +++ b/problem-43.py @@ -0,0 +1,37 @@ + +import itertools +from primes import is_prime +import string + + +def is_pandigital(num): + digits = string.digits[1:] + '0' + digits = digits[:len(str(num))] + if sorted(str(num)) == sorted(digits): + return True + else: + return False + + +if __name__ == '__main__': + results = [] + numbers = [int(''.join(x)) for x in itertools.permutations(string.digits)] + primes = [x for x in numbers if is_pandigital(x)] + for prime in primes: + if int(str(prime)[1:4]) % 2 != 0: + continue + if int(str(prime)[2:5]) % 3 != 0: + continue + if int(str(prime)[3:6]) % 5 != 0: + continue + if int(str(prime)[4:7]) % 7 != 0: + continue + if int(str(prime)[5:8]) % 11 != 0: + continue + if int(str(prime)[6:9]) % 13 != 0: + continue + if int(str(prime)[7:10]) % 17 != 0: + continue + results.append(prime) + print(results) + print(sum(results)) diff --git a/problem-44.py b/problem-44.py new file mode 100644 index 0000000..4d4316f --- /dev/null +++ b/problem-44.py @@ -0,0 +1,26 @@ + +import itertools + +def pentagonal_number(n): + return n * (3 * n - 1) / 2 + +if __name__ == '__main__': + pentagonals = [] + for i in range(1, 10000): + pentagonals.append(pentagonal_number(i)) + + pentagonals = set(pentagonals) + combos = itertools.combinations(pentagonals, 2) + lowest_diff = 9999999 + final_pents = False + for combo in combos: + total = combo[0] + combo[1] + diff = abs(combo[0] - combo[1]) + if total in pentagonals and diff in pentagonals: + if diff < lowest_diff: + lowest_diff = diff + final_pents = combo + print(final_pents) + print(lowest_diff) + + diff --git a/problem-45.py b/problem-45.py new file mode 100644 index 0000000..e0e2478 --- /dev/null +++ b/problem-45.py @@ -0,0 +1,24 @@ + +import itertools + +SAMPLES = 100000 + +def triangle_num(n): + return n * (n+1) / 2 + + +def pentagonal_num(n): + return n * (3 * n -1) / 2 + + +def hexagonal_num(n): + return n * (2 * n - 1) + + +if __name__ == '__main__': + tris = [triangle_num(x) for x in range(2, SAMPLES)] + pents = [pentagonal_num(x) for x in range(2, SAMPLES)] + hexs = [hexagonal_num(x) for x in range(2, SAMPLES)] + triplets = itertools.product(tris, pents, hexs) + print(set(tris) & set(pents) & set(hexs)) + diff --git a/problem-47.py b/problem-47.py new file mode 100644 index 0000000..c4f6f3f --- /dev/null +++ b/problem-47.py @@ -0,0 +1,14 @@ + +from primes import prime_factors + + +if __name__ == '__main__': + factors = [None, None, None, None] + for i in range(3, 1000000): + factors.append(prime_factors(i)) + factors = factors[1:] + if None in factors: continue + if all(len(set(x)) > 3 for x in factors): + print(i - 3, i, [set(x) for x in factors]) + break + diff --git a/problem-48.py b/problem-48.py new file mode 100644 index 0000000..3151691 --- /dev/null +++ b/problem-48.py @@ -0,0 +1,8 @@ + + +if __name__ == '__main__': + num = 0 + for i in range(1, 1001): + num += i ** i + print(str(num)[-10:]) + diff --git a/problem-49.py b/problem-49.py new file mode 100644 index 0000000..fff6f94 --- /dev/null +++ b/problem-49.py @@ -0,0 +1,30 @@ + +import itertools +from pprint import pprint +from primes import is_prime + +if __name__ == '__main__': + results = [] + for i in range(1000, 10000): + combos = set(''.join(x) for x in itertools.permutations(str(i))) + combos = [int(x) for x in combos if int(x) > 1000] + if len(combos) < 3: + continue + primes = [int(x) for x in combos if is_prime(int(x))] + if len(primes) < 3: + continue + elif len(primes) > 3: + poss = itertools.combinations(primes, 3) + poss = set(poss) + for p in poss: + concat = sorted(p) + if concat not in results: + results.append(concat) + else: + results.append(sorted(primes)) + + results = [list(x) for x in set(tuple(x) for x in results)] + results = sorted(results, key=lambda x: (x[0], x[1])) + for result in results: + if result[1] - result[0] == result[2] - result[1]: + print(result, str(result[0]) + str(result[1]) + str(result[2])) diff --git a/problem-50.py b/problem-50.py new file mode 100644 index 0000000..e2f6a9c --- /dev/null +++ b/problem-50.py @@ -0,0 +1,19 @@ + +from primes import sieve, is_prime +from copy import deepcopy + +if __name__ == '__main__': + primes = list(sieve(1000005)) + longest = [] + total = 0 + chain = [] + for idx, prime in enumerate(primes): + chain = [prime] + total = sum(chain) + while total < 1000000: + if is_prime(total) and len(chain) > len(longest): + longest = deepcopy(chain) + chain.append(primes[idx+len(chain)]) + total = sum(chain) + print(longest, len(longest), sum(longest)) + diff --git a/problem-52.py b/problem-52.py new file mode 100644 index 0000000..aed1590 --- /dev/null +++ b/problem-52.py @@ -0,0 +1,20 @@ + + +if __name__ == '__main__': + i = 1 + while True: + two = str(2 * i) + three = str(3 * i) + four = str(4 * i) + five = str(5 * i) + six = str(6 * i) + if ( sorted(two) \ + == sorted(three) \ + == sorted(four) \ + == sorted(five) \ + == sorted(six) + ): + break + i += 1 + print(i, two, three, four, five, six) + diff --git a/problem-54.py b/problem-54.py new file mode 100644 index 0000000..c654edb --- /dev/null +++ b/problem-54.py @@ -0,0 +1,159 @@ + +import requests + +url = 'https://projecteuler.net/project/resources/p054_poker.txt' +text = requests.get(url).text +hands = text.splitlines() + +faces = { + 'T': 10, + 'J': 11, + 'Q': 12, + 'K': 13, + 'A': 14 + } + +tests = [ + '5H 5C 6S 7S KD 2C 3S 8S 8D TD', + '2C 3S 8S 8D TD 2C 5C 7D 8S QH', + '2D 9C AS AH AC 3D 6D 7D TD QD', + '4D 6S 9H QH QC 3D 6D 7H QD QS', + '2H 2D 4C 4D 4S 3C 3D 3S 9S 9D' + ] + + +def is_straight(cards): + ranks = [x[0] for x in cards] + for idx, rank in enumerate(ranks): + try: + ranks[idx] = int(rank) + except ValueError: + ranks[idx] = faces[rank] + if max(ranks) - min(ranks) == 4 and len(set(ranks)) == 5: + return True + return False + + +def is_flush(cards): + suits = [x[1] for x in cards] + return all(x == suits[0] for x in suits) + + +def get_ranks(cards): + ranks = [x[0] for x in cards] + for idx, rank in enumerate(ranks): + try: + ranks[idx] = int(rank) + except ValueError: + ranks[idx] = faces[rank] + return ranks + + +def resolve_tie(hand_one, hand_two): + value = get_value(hand_one) + hand_one_ranks = get_ranks(hand_one) + hand_two_ranks = get_ranks(hand_two) + + if is_straight(hand_one): + if max(hand_one_ranks) > max(hand_two_ranks): + return 0 + else: + return 1 + + if value in [2, 3, 6, 7, 8]: + most_common_one = max(set(hand_one_ranks), key=hand_one_ranks.count) + most_common_two = max(set(hand_two_ranks), key=hand_two_ranks.count) + if most_common_one > most_common_two: + return 0 + elif most_common_two > most_common_one: + return 1 + else: + if value not in [6, 8]: + raise Exception('second level tie needed') + + for idx, card in enumerate(sorted(hand_one_ranks)[::-1]): + if card > sorted(hand_two_ranks)[-1-idx]: + return 0 + if card < sorted(hand_two_ranks)[-1-idx]: + return 1 + + +def get_value(cards): + assert len(cards) == 5 + ranks = [x[0] for x in cards] + for idx, rank in enumerate(ranks): + try: + ranks[idx] = int(rank) + except ValueError: + ranks[idx] = faces[rank] + + flush = is_flush(cards) + straight = is_straight(cards) + + groups = {} + for card in ranks: + try: + groups[card] += 1 + except KeyError: + groups[card] = 1 + print(groups) + group_most = max(groups.values()) + + if flush and sorted(ranks) == [10, 11, 12, 13, 14]: + # royal flush + return 0 + elif flush and straight: + # straight flush + return 1 + elif group_most == 4: + # four of a kind + return 2 + elif len(groups) == 2 and group_most == 3: + # full house + return 3 + elif flush: + # flush + return 4 + elif straight: + # straight + return 5 + elif group_most == 3: + # three of a kind + return 6 + elif group_most == 2 and len(groups) == 3: + # two pair + return 7 + elif group_most == 2 and len(groups) == 4: + # pair + return 8 + else: + # high card + return 9 + + +if __name__ == '__main__': + results = {'player_one': 0, 'player_two': 0} + for idx, hand in enumerate(hands): + print(idx) + hand = hand.split(' ') + player_one = hand[:5] + player_two = hand[5:] + player_one_value = get_value(player_one) + player_two_value = get_value(player_two) + print('player_one', player_one, player_one_value, is_flush(player_one), is_straight(player_one)) + print('player_two', player_two, player_two_value, is_flush(player_two), is_straight(player_two)) + if player_one_value == player_two_value: + if resolve_tie(player_one, player_two) == 0: + print('player_one_wins') + results['player_one'] += 1 + elif resolve_tie(player_one, player_two) == 1: + print('player_two wins') + results['player_two'] += 1 + elif player_one_value < player_two_value: + print('player_one wins') + results['player_one'] += 1 + else: + print('player_two wins') + results['player_two'] += 1 + print(results) +