Moved 20 to 26 to Python.
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
|
from lib_misc import factorial
|
||||||
|
|
||||||
|
|
||||||
def euler_020():
|
def euler_020():
|
||||||
return 0
|
f_100 = factorial(100)
|
||||||
|
return sum(map(int, str(f_100)))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
assert(euler_020() == 1074)
|
assert(euler_020() == 648)
|
||||||
print("e020.py: {}".format(euler_020()))
|
print("e020.py: {}".format(euler_020()))
|
||||||
|
|||||||
15
python/e021.py
Normal file
15
python/e021.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from lib_misc import sum_proper_divisors
|
||||||
|
|
||||||
|
|
||||||
|
def euler_021():
|
||||||
|
t = 0
|
||||||
|
for n in range(1, 10000):
|
||||||
|
s = sum_proper_divisors(n)
|
||||||
|
if n != s and n == sum_proper_divisors(s):
|
||||||
|
t += n
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
assert(euler_021() == 31626)
|
||||||
|
print("e021.py: {}".format(euler_021()))
|
||||||
17
python/e022.py
Normal file
17
python/e022.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
def get_score_for_name(name):
|
||||||
|
return sum([ord(c) - ord('A') + 1 for c in name if not c == '"'])
|
||||||
|
|
||||||
|
|
||||||
|
def euler_022():
|
||||||
|
with open('../txt/EulerProblem022.txt', 'r') as f:
|
||||||
|
names = f.read().split(',')
|
||||||
|
names.sort()
|
||||||
|
s = sum([(i + 1) * get_score_for_name(name)
|
||||||
|
for i, name in enumerate(names)])
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
assert(get_score_for_name('COLIN') == 53)
|
||||||
|
assert(euler_022() == 871198282)
|
||||||
|
print("e022.py: {}".format(euler_022()))
|
||||||
@@ -1,40 +1,28 @@
|
|||||||
import math
|
from lib_misc import sum_proper_divisors
|
||||||
|
|
||||||
|
|
||||||
def get_proper_divisors(n):
|
|
||||||
proper_divisors = set([1])
|
|
||||||
for i in range(2, int(math.sqrt(n)) + 1):
|
|
||||||
if n % i == 0:
|
|
||||||
proper_divisors.add(i)
|
|
||||||
proper_divisors.add(n / i)
|
|
||||||
return proper_divisors
|
|
||||||
|
|
||||||
|
|
||||||
def is_abundant(n):
|
def is_abundant(n):
|
||||||
return sum(get_proper_divisors(n)) > n
|
return sum_proper_divisors(n) > n
|
||||||
|
|
||||||
|
|
||||||
def get_abundant_numbers_smaller(n):
|
def is_sum_of_two_abundant(n, abundant_numbers, abundant_numbers_set):
|
||||||
ret = []
|
for a in abundant_numbers:
|
||||||
for i in range(1, n):
|
if a > n:
|
||||||
if is_abundant(i):
|
|
||||||
ret.append(i)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def is_sum_of_two_abundant(n, abundant_numbers):
|
|
||||||
abundant_numbers_set = set(abundant_numbers)
|
|
||||||
for a1 in abundant_numbers:
|
|
||||||
if a1 > n:
|
|
||||||
return False
|
return False
|
||||||
elif (n - a1) in abundant_numbers_set:
|
d = n - a
|
||||||
|
if d in abundant_numbers_set:
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def euler_023():
|
||||||
|
abundant_numbers = [n for n in range(1, 28123 + 1) if is_abundant(n)]
|
||||||
|
abundant_numbers_set = set(abundant_numbers)
|
||||||
|
return sum([n for n in range(1, 28123 + 1)
|
||||||
|
if not is_sum_of_two_abundant(n, abundant_numbers,
|
||||||
|
abundant_numbers_set)])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
abundant_numbers = get_abundant_numbers_smaller(30000)
|
print("e023.py: {}".format(euler_023()))
|
||||||
cannot_be_written_as_sum_of_abundant = []
|
assert(euler_023() == 4179871)
|
||||||
for i in range(28129):
|
|
||||||
if not is_sum_of_two_abundant(i, abundant_numbers):
|
|
||||||
cannot_be_written_as_sum_of_abundant.append(i)
|
|
||||||
print(sum(cannot_be_written_as_sum_of_abundant))
|
|
||||||
|
|||||||
@@ -1,2 +1,31 @@
|
|||||||
from itertools import permutations
|
from itertools import permutations
|
||||||
print("".join(list(permutations("0123456789"))[1000000-1]))
|
|
||||||
|
|
||||||
|
def euler_024_library():
|
||||||
|
return int("".join(list(permutations("0123456789"))[1000000 - 1]))
|
||||||
|
|
||||||
|
|
||||||
|
def permutations_(iterable):
|
||||||
|
if not iterable:
|
||||||
|
yield iterable
|
||||||
|
for i in range(len(iterable)):
|
||||||
|
elem = iterable[i:i + 1]
|
||||||
|
rest = iterable[:i] + iterable[i + 1:]
|
||||||
|
for ps in permutations_(rest):
|
||||||
|
yield elem + ps
|
||||||
|
|
||||||
|
|
||||||
|
def n_th(generator, n):
|
||||||
|
for i in range(n):
|
||||||
|
next(generator)
|
||||||
|
return next(generator)
|
||||||
|
|
||||||
|
|
||||||
|
def euler_024():
|
||||||
|
g = permutations_("0123456789")
|
||||||
|
return int(n_th(g, 1000000 - 1))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("e024.py: {}".format(euler_024()))
|
||||||
|
assert(euler_024() == 2783915460)
|
||||||
|
|||||||
113
python/e025.py
113
python/e025.py
@@ -1,109 +1,12 @@
|
|||||||
from copy import deepcopy
|
from lib_fibonacci import fibonacci_generator
|
||||||
from itertools import islice
|
|
||||||
|
|
||||||
|
|
||||||
def primes(n):
|
def euler_025():
|
||||||
""" Nice way to calculate primes. Should be fast. """
|
for i, f in enumerate(fibonacci_generator()):
|
||||||
l = range(2, n + 1)
|
if len(str(f)) >= 1000:
|
||||||
_l = []
|
return i + 1
|
||||||
while True:
|
|
||||||
p = l[0]
|
|
||||||
if p * p > n:
|
|
||||||
return _l + l
|
|
||||||
l = [i for i in l if i % p != 0]
|
|
||||||
_l.append(p)
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_decimal_places(numerator, denominator):
|
|
||||||
numerator = (numerator - (numerator / denominator) * denominator) * 10
|
|
||||||
digits = []
|
|
||||||
while True:
|
|
||||||
digit = numerator / denominator
|
|
||||||
numerator = (numerator - digit * denominator) * 10
|
|
||||||
digits.append(digit)
|
|
||||||
if digits[-3:] == [0, 0, 0]:
|
|
||||||
raise StopIteration
|
|
||||||
yield digit
|
|
||||||
|
|
||||||
|
|
||||||
def has_cycle(decimal_places, n):
|
|
||||||
d = decimal_places
|
|
||||||
return list(islice(d, 0, n)) == list(islice(d, 0, n)) and \
|
|
||||||
list(islice(d, 0, n)) == list(islice(d, 0, n))
|
|
||||||
|
|
||||||
|
|
||||||
def f_025_1():
|
|
||||||
""" Second try. I realized that only primes must be
|
|
||||||
checked. Therefore, my brute force approach worked. """
|
|
||||||
l = []
|
|
||||||
for d in primes(1000):
|
|
||||||
for i in range(5, 10000):
|
|
||||||
decimal_places = calculate_decimal_places(1, d)
|
|
||||||
if has_cycle(decimal_places, i):
|
|
||||||
l.append((i, d))
|
|
||||||
break
|
|
||||||
print(max(l))
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_cycle(numerator, denominator):
|
|
||||||
numerator = (numerator - (numerator / denominator) * denominator) * 10
|
|
||||||
remainders = set([])
|
|
||||||
while True:
|
|
||||||
digit = numerator / denominator
|
|
||||||
remainder = (numerator - digit * denominator)
|
|
||||||
if remainder in remainders:
|
|
||||||
raise StopIteration
|
|
||||||
remainders.add(remainder)
|
|
||||||
numerator = remainder * 10
|
|
||||||
yield digit
|
|
||||||
|
|
||||||
|
|
||||||
def f_025_2():
|
|
||||||
""" Understood trick with remembering remainder... """
|
|
||||||
s = [(len(list(calculate_cycle(1, d))), d)
|
|
||||||
for d in range(1, 1001)]
|
|
||||||
print(max(s))
|
|
||||||
|
|
||||||
|
|
||||||
def f_025_3():
|
|
||||||
""" Only testing primes... """
|
|
||||||
s = [(len(list(calculate_cycle(1, d))), d)
|
|
||||||
for d in primes(10000)]
|
|
||||||
print(max(s))
|
|
||||||
|
|
||||||
|
|
||||||
f_025_3()
|
|
||||||
|
|
||||||
|
|
||||||
#print([(find_cycle_count(calculate_decimal_places(1, d)), d)
|
|
||||||
# for d in range(1, 100)])
|
|
||||||
|
|
||||||
#print(find_cycle_count(calculate_decimal_places(22, 7)))
|
|
||||||
|
|
||||||
#l = []
|
|
||||||
#for d in range(1, 1000):
|
|
||||||
# for i in range(5, 1000):
|
|
||||||
# decimal_places = calculate_decimal_places(1, d)
|
|
||||||
# if has_cycle_one_off(decimal_places, i):
|
|
||||||
# l.append((i, d))
|
|
||||||
# break
|
|
||||||
# decimal_places = calculate_decimal_places(1, d)
|
|
||||||
# if has_cycle(decimal_places, i):
|
|
||||||
# l.append((i, d))
|
|
||||||
# break
|
|
||||||
|
|
||||||
#def find_cycle_count(decimal_places):
|
|
||||||
# cycles = []
|
|
||||||
# for digit in decimal_places:
|
|
||||||
# new_cycles = []
|
|
||||||
# for cycle in cycles:
|
|
||||||
# digits, length = cycle
|
|
||||||
# if digits[0] == digit:
|
|
||||||
# if len(digits[1:]) == 0:
|
|
||||||
# return length
|
|
||||||
# new_cycles.append((digits[1:], length))
|
|
||||||
# new_cycles.append((digits + [digit], length + 1))
|
|
||||||
# new_cycles.append(([digit], 1))
|
|
||||||
# cycles = new_cycles
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("e025.py: {}".format(euler_025()))
|
||||||
|
assert(euler_025() == 4782)
|
||||||
|
|||||||
@@ -1,38 +1,31 @@
|
|||||||
def primes(n):
|
from itertools import count
|
||||||
""" Nice way to calculate primes. Should be fast. """
|
|
||||||
l = range(2, n + 1)
|
|
||||||
_l = []
|
|
||||||
while True:
|
|
||||||
p = l[0]
|
|
||||||
if p * p > n:
|
|
||||||
return _l + l
|
|
||||||
l = [i for i in l if i % p != 0]
|
|
||||||
_l.append(p)
|
|
||||||
|
|
||||||
|
|
||||||
def produce_prime(a, b, n, primes):
|
def get_cycle_count(nominator, denominator):
|
||||||
x = n*n + a*n + b
|
assert(nominator == 1)
|
||||||
return x in primes
|
remainders = {}
|
||||||
|
remainder = nominator
|
||||||
|
results = []
|
||||||
|
for i in count():
|
||||||
|
result = remainder // denominator
|
||||||
|
remainder = remainder % denominator
|
||||||
|
results.append(result)
|
||||||
|
if remainder in remainders:
|
||||||
|
return i - remainders[remainder]
|
||||||
|
else:
|
||||||
|
remainders[remainder] = i
|
||||||
|
if remainder == 0:
|
||||||
|
return 0
|
||||||
|
remainder *= 10
|
||||||
|
|
||||||
|
|
||||||
|
def euler_026():
|
||||||
def f_027():
|
return max([(get_cycle_count(1, i), i) for i in range(1, 1000)])[1]
|
||||||
""" n^2 + a*n + b
|
|
||||||
1) b must be prime
|
|
||||||
"""
|
|
||||||
p6 = set(primes(1000000))
|
|
||||||
p3 = primes(1000)
|
|
||||||
options = [(a, b)
|
|
||||||
for a in range(1, 1000, 2)
|
|
||||||
for b in p3]
|
|
||||||
|
|
||||||
print(len(options))
|
|
||||||
for n in range(100):
|
|
||||||
options = [(a, b)
|
|
||||||
for a, b in options
|
|
||||||
if produce_prime(a, b, n, p6)]
|
|
||||||
print(options)
|
|
||||||
print(len(options))
|
|
||||||
|
|
||||||
|
|
||||||
f_027()
|
if __name__ == "__main__":
|
||||||
|
assert(get_cycle_count(1, 7) == 6)
|
||||||
|
assert(get_cycle_count(1, 10) == 0)
|
||||||
|
assert(get_cycle_count(1, 6) == 1)
|
||||||
|
print("e026.py: {}".format(euler_026()))
|
||||||
|
assert(euler_026() == 983)
|
||||||
|
|||||||
@@ -134,4 +134,46 @@ def collatz_sequence_length(n):
|
|||||||
return length + collatz_sequence_length(n // 2)
|
return length + collatz_sequence_length(n // 2)
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=10000)
|
||||||
|
def factorial(n):
|
||||||
|
if n == 1:
|
||||||
|
return 1
|
||||||
|
return n * factorial(n - 1)
|
||||||
|
|
||||||
|
|
||||||
|
def proper_divisors(n):
|
||||||
|
"""
|
||||||
|
Returns the list of divisors for n excluding n.
|
||||||
|
"""
|
||||||
|
if n < 2:
|
||||||
|
return []
|
||||||
|
divisors = [1, ]
|
||||||
|
d = 2
|
||||||
|
while d * d <= n:
|
||||||
|
if n % d == 0:
|
||||||
|
divisors.append(d)
|
||||||
|
d += 1
|
||||||
|
# Ignore first element and iterate list backwards.
|
||||||
|
for d in divisors[1:][::-1]:
|
||||||
|
q = n // d
|
||||||
|
if q != d:
|
||||||
|
divisors.append(q)
|
||||||
|
return divisors
|
||||||
|
|
||||||
|
|
||||||
|
def sum_proper_divisors(n):
|
||||||
|
"""
|
||||||
|
Returns the sum of proper divisors of a number.
|
||||||
|
"""
|
||||||
|
if n < 2:
|
||||||
|
return 0
|
||||||
|
s = 1
|
||||||
|
d = 2
|
||||||
|
while d * d <= n:
|
||||||
|
if n % d == 0:
|
||||||
|
s += d
|
||||||
|
q = n // d
|
||||||
|
if q != d:
|
||||||
|
s += q
|
||||||
|
d += 1
|
||||||
|
return s
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ try:
|
|||||||
from .lib_misc import even, odd
|
from .lib_misc import even, odd
|
||||||
from .lib_misc import collatz_sequence
|
from .lib_misc import collatz_sequence
|
||||||
from .lib_misc import collatz_sequence_length
|
from .lib_misc import collatz_sequence_length
|
||||||
|
from .lib_misc import factorial
|
||||||
|
from .lib_misc import proper_divisors, sum_proper_divisors
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
from lib_misc import is_palindrome_integer
|
from lib_misc import is_palindrome_integer
|
||||||
from lib_misc import is_palindrome_string
|
from lib_misc import is_palindrome_string
|
||||||
@@ -19,6 +21,8 @@ except ModuleNotFoundError:
|
|||||||
from lib_misc import even, odd
|
from lib_misc import even, odd
|
||||||
from lib_misc import collatz_sequence
|
from lib_misc import collatz_sequence
|
||||||
from lib_misc import collatz_sequence_length
|
from lib_misc import collatz_sequence_length
|
||||||
|
from lib_misc import factorial
|
||||||
|
from lib_misc import proper_divisors, sum_proper_divisors
|
||||||
|
|
||||||
|
|
||||||
class TestPrimeMethods(unittest.TestCase):
|
class TestPrimeMethods(unittest.TestCase):
|
||||||
@@ -70,6 +74,27 @@ class TestPrimeMethods(unittest.TestCase):
|
|||||||
[13, 40, 20, 10, 5, 16, 8, 4, 2, 1])
|
[13, 40, 20, 10, 5, 16, 8, 4, 2, 1])
|
||||||
self.assertEqual(collatz_sequence_length(13), 10)
|
self.assertEqual(collatz_sequence_length(13), 10)
|
||||||
|
|
||||||
|
def test_factorial(self):
|
||||||
|
self.assertEqual(factorial(1), 1)
|
||||||
|
self.assertEqual(factorial(3), 6)
|
||||||
|
self.assertEqual(factorial(10), 3628800)
|
||||||
|
|
||||||
|
def test_proper_divisors(self):
|
||||||
|
self.assertEqual(proper_divisors(0), [])
|
||||||
|
self.assertEqual(proper_divisors(1), [])
|
||||||
|
self.assertEqual(proper_divisors(2), [1])
|
||||||
|
self.assertEqual(proper_divisors(4), [1, 2])
|
||||||
|
self.assertEqual(proper_divisors(220), [
|
||||||
|
1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110])
|
||||||
|
|
||||||
|
def test_sum_proper_divisors(self):
|
||||||
|
self.assertEqual(sum_proper_divisors(0), 0)
|
||||||
|
self.assertEqual(sum_proper_divisors(1), 0)
|
||||||
|
self.assertEqual(sum_proper_divisors(2), 1)
|
||||||
|
self.assertEqual(sum_proper_divisors(3), 1)
|
||||||
|
self.assertEqual(sum_proper_divisors(220), 284)
|
||||||
|
self.assertEqual(sum_proper_divisors(284), 220)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ except ModuleNotFoundError:
|
|||||||
|
|
||||||
def prime_factors(n):
|
def prime_factors(n):
|
||||||
"""
|
"""
|
||||||
|
Returns a list of prime factors for n.
|
||||||
|
|
||||||
:param n: number for which prime factors should be returned
|
:param n: number for which prime factors should be returned
|
||||||
"""
|
"""
|
||||||
# TODO: Look into using a prime wheel instead.
|
# TODO: Look into using a prime wheel instead.
|
||||||
@@ -30,10 +32,12 @@ def prime_factors(n):
|
|||||||
|
|
||||||
def prime_factors_count(n):
|
def prime_factors_count(n):
|
||||||
"""
|
"""
|
||||||
|
Returns a dictionay of primes where each key is a prime
|
||||||
|
and the value how many times that prime is part of the factor of n.
|
||||||
|
|
||||||
:param n: numober for which prime factor counts are returned
|
:param n: numober for which prime factor counts are returned
|
||||||
:returns: a dict where they key is a prime vactor and the value
|
:returns: a dict where they key is a prime and the value
|
||||||
the count of how of that value occurs
|
the count of how often that value occurs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return get_item_counts(prime_factors(n))
|
return get_item_counts(prime_factors(n))
|
||||||
|
|||||||
Reference in New Issue
Block a user