diff --git a/python/e006.py b/python/e006.py index 373b303..d4c9f8d 100644 --- a/python/e006.py +++ b/python/e006.py @@ -1,5 +1,14 @@ -def euler_006(): - return 0 -assert(euler_006() == 233168) +def diff_between_sum_of_squares_and_square_sum(n): + a = sum([x for x in range(1, n + 1)])**2 + b = sum([x**2 for x in range(1, n + 1)]) + return a - b + + +def euler_006(): + return diff_between_sum_of_squares_and_square_sum(100) + + +assert(diff_between_sum_of_squares_and_square_sum(10) == 2640) +assert(euler_006() == 25164150) print("e006.py: {}".format(euler_006())) diff --git a/python/e007.py b/python/e007.py new file mode 100644 index 0000000..8126396 --- /dev/null +++ b/python/e007.py @@ -0,0 +1,32 @@ +from lib_prime import prime_nth + + +def euler_007(): + return prime_nth(10001) + + +def euler_007_forum_4r0(): + """ This solution is very naiv. I only got intrigued by + it because it looked so weird and simple in the beginning. + Turned out it is a straight forward and naiv as it gets once + you format the code properly and give somewhat meaningful + variable names. """ + prime_count = 0 + divisor = 2 + prime = 2 + while prime_count != 10001: + print(prime_count) + divisor = 2 + while divisor <= prime: + if prime % divisor == 0 and divisor != prime: + divisor = prime + elif divisor == prime: + prime_count += 1 + divisor += 1 + prime += 1 + prime -= 1 + return prime + + +assert(euler_007() == 104743) +print("e007.py: {}".format(euler_007())) diff --git a/python/e008.py b/python/e008.py new file mode 100644 index 0000000..65c05f6 --- /dev/null +++ b/python/e008.py @@ -0,0 +1,44 @@ +from lib_misc import product + + +def remove_newlines(s): + import re + return re.sub(r'\n', '', s) + + +digits_string = """ +73167176531330624919225119674426574742355349194934 +96983520312774506326239578318016984801869478851843 +85861560789112949495459501737958331952853208805511 +12540698747158523863050715693290963295227443043557 +66896648950445244523161731856403098711121722383113 +62229893423380308135336276614282806444486645238749 +30358907296290491560440772390713810515859307960866 +70172427121883998797908792274921901699720888093776 +65727333001053367881220235421809751254540594752243 +52584907711670556013604839586446706324415722155397 +53697817977846174064955149290862569321978468622482 +83972241375657056057490261407972968652414535100474 +82166370484403199890008895243450658541227588666881 +16427171479924442928230863465674813919123162824586 +17866458359124566529476545682848912883142607690042 +24219022671055626321111109370544217506941658960408 +07198403850962455444362981230987879927244284909188 +84580156166097919133875499200524063689912560717606 +05886116467109405077541002256983155200055935729725 +71636269561882670428252483600823257530420752963450 +""" +digits = [int(d) for d in remove_newlines(digits_string)] + + +def get_largest_product_of_n_digits(digits, n): + return max((product(digits[i:i + n]) for i in range(len(digits)))) + + +def euler_008(): + return get_largest_product_of_n_digits(digits, 13) + + +assert(get_largest_product_of_n_digits(digits, 4) == 5832) +assert(euler_008() == 23514624000) +print("e008.py: {}".format(euler_008())) diff --git a/python/e009.py b/python/e009.py new file mode 100644 index 0000000..68f336b --- /dev/null +++ b/python/e009.py @@ -0,0 +1,10 @@ +def euler_009(): + for a in range(1, 251): + for b in range(a + 1, 501): + c = 1000 - a - b + if a * a + b * b == c * c: + return a * b * c + + +assert(euler_009() == 31875000) +print("e009.py: {}".format(euler_009())) diff --git a/python/e010.py b/python/e010.py new file mode 100644 index 0000000..3ec0e9c --- /dev/null +++ b/python/e010.py @@ -0,0 +1,9 @@ +from lib_prime import primes + + +def euler_010(): + return sum(primes(2 * 10**6)) + + +assert(euler_010() == 142913828922) +print("e010.py: {}".format(euler_010())) diff --git a/python/e011.py b/python/e011.py new file mode 100644 index 0000000..eb54d75 --- /dev/null +++ b/python/e011.py @@ -0,0 +1,61 @@ +from lib_misc import product +s = """ +08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 +49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 +81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 +52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 +22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 +24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 +32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 +67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 +24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 +21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 +78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 +16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 +86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 +19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 +04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 +88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 +04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 +20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 +20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 +01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 +""" + + +def get_index(xs, index, default): + if index < 0: + return default + try: + return xs[index] + except IndexError: + return default + + +def get_lists_for_all_directions(): + # horizontal lists + hss = [list(map(int, h.split())) for h in s.split('\n') if h] + # vertical lists + vss = [list(vs) for vs in zip(*hss)] + # diagonal from top left to bottom right + dss_1 = [[get_index(hs, -19 + i + j, 1) for j, hs in enumerate(hss)] + for i in range(39)] + # diagonal from bottom left to top right + dss_2 = [[get_index(hs, -19 + i + j, 1) for j, hs in enumerate(hss[::-1])] + for i in range(39)] + # all lists + xss = hss + vss + dss_1 + dss_2 + return xss + + +def get_largest_product_of_n_digits(xs, n): + return max([product(xs[i:i + n]) for i in range(len(xs))]) + + +def euler_011(): + xss = get_lists_for_all_directions() + return max([get_largest_product_of_n_digits(xs, 4) for xs in xss]) + + +assert(euler_011() == 70600674) +print("e011.py: {}".format(euler_011())) diff --git a/python/lib_prime.py b/python/lib_prime.py index 2f57935..7a11c06 100644 --- a/python/lib_prime.py +++ b/python/lib_prime.py @@ -5,6 +5,9 @@ except ModuleNotFoundError: def prime_factors(n): + """ + :param n: number for which prime factors should be returned + """ # TODO: Look into using a prime wheel instead. factors = [] rest = n @@ -24,4 +27,83 @@ def prime_factors(n): def prime_factors_count(n): + """ + + :param n: numober for which prime factor counts are returned + :returns: a dict where they key is a prime vactor and the value + the count of how of that value occurs + + """ return get_item_counts(prime_factors(n)) + + +def is_prime(n): + """Returns True if n is prime and False otherwise. + + :param n: number to be checked + + """ + if n < 2: + return False + if n == 2 or n == 3: + return True + if n % 2 == 0: + return False + d = 3 + while d * d <= n: + if n % d == 0: + return False + d += 2 + return True + + +def prime_nth(n): + """Returns the nth prime number. The first number + is 1 indexed, i.e. n = 1 -> 2, n = 2 -> 3, etc. + + :param n: + + """ + if n == 1: + return 2 + if n == 2: + return 3 + p = 5 + i = 3 + while i < n: + p = p + 2 + if is_prime(p): + i += 1 + return p + + +def primes(n_max): + """ + Returns a list of all primes smaller n based + on sieve of erasthones algorithm. + + If bitarray module is installed it will be used + for the array, otherwise a regular Python list is + used. The function should work for much larger + numbers with bitarray. + + :param n_max: + """ + try: + import bitarray + b = bitarray.bitarray(n_max) + b.setall(True) + except ModuleNotFoundError: + b = [True for _ in range(n_max)] + n = 1 + b[n - 1] = False + while n * n <= n_max: + if b[n - 1] is True: + for i in range(n + n, n_max + 1, n): + b[i - 1] = False + n += 1 + ps = [] + for i in range(1, n_max + 1): + if b[i - 1]: + ps.append(i) + return ps diff --git a/python/lib_prime_tests.py b/python/lib_prime_tests.py index 1621ea4..fd29747 100644 --- a/python/lib_prime_tests.py +++ b/python/lib_prime_tests.py @@ -2,9 +2,15 @@ import unittest try: from .lib_prime import prime_factors from .lib_prime import prime_factors_count + from .lib_prime import is_prime + from .lib_prime import prime_nth + from .lib_prime import primes except ModuleNotFoundError: from lib_prime import prime_factors from lib_prime import prime_factors_count + from lib_prime import is_prime + from lib_prime import prime_nth + from lib_prime import primes class TestPrimeMethods(unittest.TestCase): @@ -20,6 +26,39 @@ class TestPrimeMethods(unittest.TestCase): self.assertEqual(prime_factors_count(2), {2: 1}) self.assertEqual(prime_factors_count(147), {3: 1, 7: 2}) + def test_is_prime(self): + self.assertTrue(is_prime(2)) + self.assertTrue(is_prime(3)) + self.assertTrue(is_prime(5)) + self.assertTrue(is_prime(7)) + self.assertTrue(is_prime(11)) + self.assertTrue(is_prime(13)) + self.assertTrue(is_prime(101)) + + self.assertFalse(is_prime(0)) + self.assertFalse(is_prime(1)) + self.assertFalse(is_prime(4)) + self.assertFalse(is_prime(6)) + self.assertFalse(is_prime(8)) + self.assertFalse(is_prime(9)) + self.assertFalse(is_prime(10)) + self.assertFalse(is_prime(12)) + self.assertFalse(is_prime(323)) + + def test_get_nth_prime(self): + self.assertEqual(prime_nth(1), 2) + self.assertEqual(prime_nth(2), 3) + self.assertEqual(prime_nth(3), 5) + self.assertEqual(prime_nth(4), 7) + self.assertEqual(prime_nth(5), 11) + self.assertEqual(prime_nth(6), 13) + + def test_primes(self): + self.assertEqual(primes(19), [2, 3, 5, 7, 11, 13, 17, 19]) + self.assertEqual(primes(20), [2, 3, 5, 7, 11, 13, 17, 19]) + self.assertEqual(primes(25), [2, 3, 5, 7, 11, 13, 17, 19, 23]) + self.assertEqual(primes(1), []) + if __name__ == '__main__': unittest.main()