Finished existing ipython solutions to python. Ready to continue in pure python.

main
Felix Martin 2019-07-18 14:23:44 -04:00
parent c624e6ac52
commit 45e0cd8a78
13 changed files with 425 additions and 25 deletions

View File

@ -1,8 +1,31 @@
from lib_misc import gcd
from lib_misc import get_digit_count
def add_fractions(n1, d1, n2, d2):
d = d1 * d2
n1 = n1 * (d // d1)
n2 = n2 * (d // d2)
n = n1 + n2
p = gcd(n, d)
return (n // p, d // p)
def next_expension(n, d):
n, d = add_fractions(1, 1, n, d)
return add_fractions(1, 1, d, n)
def euler_057():
return 0
c = 0
n, d = (3, 2)
for i in range(1000):
if get_digit_count(n) > get_digit_count(d):
c += 1
n, d = next_expension(n, d)
return c
if __name__ == "__main__":
print("e057.py: " + str(euler_057()))
assert(euler_057() == 0)
assert(euler_057() == 153)

View File

@ -1,8 +1,33 @@
from lib_prime import is_prime
def get_corner_values(side_length):
def get_last_corner_value(side_length):
return side_length * side_length
if side_length == 1:
return [1]
return [get_last_corner_value(side_length) - i * (side_length - 1)
for i in range(0, 4)][::-1]
def euler_058():
return 0
n = 1
count_primes = 0
count_total = 0
while True:
for v in get_corner_values(n):
count_total += 1
if is_prime(v):
count_primes += 1
ratio = count_primes / count_total
if ratio != 0 and ratio < 0.10:
# print("n: {} count_total: {} count_primes: {} ratio: {}"
# .format(n, count_total, count_primes, ratio))
return n
n += 2
if __name__ == "__main__":
print("e058.py: " + str(euler_058()))
assert(euler_058() == 0)
assert(euler_058() == 26241)

View File

@ -1,8 +1,61 @@
def get_encrypted_msg():
with open("../txt/EulerProblem059.txt", "r") as f:
msg = [int(d) for d in f.read().split(',')]
return msg
def get_words():
with open("../txt/EulerProblem042.txt", "r") as f:
words = [w.strip('"') for w in f.read().split(",")]
return set(words)
def generate_keys():
alphabet = list(map(chr, range(97, 123)))
return [(ord(a), ord(b), ord(c))
for a in alphabet
for b in alphabet
for c in alphabet]
def to_string(msg):
return "".join(map(chr, msg))
def to_ascii(msg):
return list(map(ord, msg))
def decrypt_msg(key, msg):
return [d ^ key[i % len(key)] for i, d in enumerate(msg)]
def clean_word(word):
return word.strip('').strip(",").strip(".").strip("!").strip("?").upper()
def test_key(key, msg, word_list):
msg = to_string(decrypt_msg(key, msg))
word_count = 0
words = msg.split(" ")
for word in words:
if clean_word(word) in word_list:
word_count += 1
return word_count / len(words)
def euler_059():
return 0
msg = get_encrypted_msg()
word_list = get_words()
keys = generate_keys()
ss = [(test_key(key, msg, word_list), key) for key in keys]
s = sorted(ss, reverse=True)[0]
key = s[1]
s = sum(decrypt_msg(key, msg))
return s
if __name__ == "__main__":
print("e059.py: " + str(euler_059()))
assert(euler_059() == 0)
assert(euler_059() == 107359)

View File

@ -1,8 +1,55 @@
from itertools import combinations
from lib_prime import primes, is_prime
def concatenate_all(numbers):
result = []
for a, b in combinations(numbers, 2):
result.append([a, b])
result.append([b, a])
return result
def concatentation_is_prime(a, b):
ab = int(str(a) + str(b))
ba = int(str(b) + str(a))
if is_prime(ab) and is_prime(ba):
return True
else:
return False
def euler_060():
return 0
""" Hahaha. I have no idea what I was thinking
when writing this code. Beautiful! """
potentials = []
new_potentials = []
done = False
for p in primes(100000):
if done:
break
potentials += new_potentials
new_potentials = []
for potential in potentials:
all_concatenations_prime = True
for prime in potential:
if not concatentation_is_prime(p, prime):
all_concatenations_prime = False
break
if all_concatenations_prime:
new_potential = list(potential)
new_potential.append(p)
if len(new_potential) > 4:
# print(new_potential)
s = sum(new_potential)
done = True
break
new_potentials.append(new_potential)
if p < 15:
potentials.append([p])
return s
if __name__ == "__main__":
print("e060.py: " + str(euler_060()))
assert(euler_060() == 0)
assert(euler_060() == 26033)

View File

@ -1,8 +1,59 @@
def get_four_digit_numbers(function):
r = []
n = 1
f = function
while f(n) < 10000:
if f(n) > 999:
r.append(f(n))
n += 1
return r
def search_solution(aggregator, polygonals):
if not polygonals:
if is_cyclic(aggregator[-1], aggregator[0]):
return aggregator
else:
return []
if not aggregator:
for polygonal in polygonals:
for number in polygonal:
aggregator.append(number)
s = search_solution(
aggregator, [p for p in polygonals if p != polygonal])
if s:
return s
aggregator.pop()
for polygonal in polygonals:
for number in polygonal:
if is_cyclic(aggregator[-1], number) and number not in aggregator:
aggregator.append(number)
s = search_solution(
aggregator, [p for p in polygonals if p != polygonal])
if s:
return s
aggregator.pop()
return []
def is_cyclic(a, b):
return str(a)[-2:] == str(b)[:2]
def euler_061():
return 0
triangles = get_four_digit_numbers(lambda n: n * (n + 1) // 2)
squares = get_four_digit_numbers(lambda n: n**2)
pentas = get_four_digit_numbers(lambda n: n * (3 * n - 1) // 2)
hexas = get_four_digit_numbers(lambda n: n * (2 * n - 1))
heptas = get_four_digit_numbers(lambda n: n * (5 * n - 3) // 2)
octas = get_four_digit_numbers(lambda n: n * (3 * n - 2))
s = search_solution([], [triangles, squares, pentas, hexas, heptas, octas])
s = sum(s)
return s
if __name__ == "__main__":
print("e061.py: " + str(euler_061()))
assert(euler_061() == 0)
assert(euler_061() == 28684)

View File

@ -1,8 +1,20 @@
def euler_062():
return 0
solutions = {}
for n in range(1, 10000):
cube = n * n * n
try:
key = "".join(sorted(str(cube)))
solutions[key].append(cube)
if len(solutions[key]) > 4:
# print(solutions[key])
s = solutions[key][0]
break
except KeyError:
solutions[key] = [cube]
return s
if __name__ == "__main__":
print("e062.py: " + str(euler_062()))
assert(euler_062() == 0)
assert(euler_062() == 127035954683)

View File

@ -1,8 +1,22 @@
from lib_misc import get_digit_count
def get_n_digit_positive_integers(n):
r = []
i = 1
while True:
if get_digit_count(i ** n) == n:
r.append(i ** n)
if get_digit_count(i ** n) > n:
return r
i += 1
def euler_063():
return 0
s = sum([len(get_n_digit_positive_integers(n)) for n in range(1, 1000)])
return s
if __name__ == "__main__":
print("e063.py: " + str(euler_063()))
assert(euler_063() == 0)
assert(euler_063() == 49)

View File

@ -1,8 +1,69 @@
import math
def get_floor_sqrt(n):
return math.floor(math.sqrt(n))
def next_expansion(current_a, current_nominator,
current_denominator, original_number):
# Less typing
cn = current_nominator
cd = current_denominator
# Step 1: Multiply the fraction so that we can use the third binomial
# formula. Make sure we can reduce the nominator.
assert((original_number - cd * cd) % cn == 0)
# The new nominator is the denominator since we multiply with (x + cd) and
# then reduce the previous nominator. The new denominator is calculated by
# applying the third binomial formula and then by divided by the previous
# nominator.
cn, cd = cd, (original_number - cd * cd) // cn
# Step 2: Calculate the next a by finding the next floor square root.
next_a = math.floor((math.sqrt(original_number) + cn) // cd)
# Step 3: Remove next a from the fraction by substracting it.
cn = cn - next_a * cd
cn *= -1
return next_a, cn, cd
def get_continued_fraction_sequence(n):
# If number is a square number we return it.
floor_sqrt = get_floor_sqrt(n)
if n == floor_sqrt * floor_sqrt:
return ((floor_sqrt), [])
# Otherwise, we calculate the next expansion till we
# encounter a step a second time.
a = floor_sqrt
cn = a
cd = 1
sequence = []
previous_steps = []
while not (a, cn, cd) in previous_steps:
# print("a: {} cn: {} cd: {}".format(a, cn, cd))
previous_steps.append((a, cn, cd))
a, cn, cd = next_expansion(a, cd, cn, n)
sequence.append(a)
sequence.pop()
return ((floor_sqrt), sequence)
def get_period(n):
_, sequence = get_continued_fraction_sequence(n)
return len(sequence)
def euler_064():
return 0
s = len([n for n in range(1, 10001) if get_period(n) % 2 != 0])
return s
if __name__ == "__main__":
print("e064.py: " + str(euler_064()))
assert(euler_064() == 0)
assert(euler_064() == 1322)

View File

@ -1,8 +1,21 @@
from e057 import add_fractions
def next_expansion(previous_numerator, previous_denumerator, value):
if previous_numerator == 0:
return (value, 1)
return add_fractions(previous_denumerator, previous_numerator, value, 1)
def euler_065():
return 0
e_sequence = [2] + [n for i in range(2, 1000, 2) for n in (1, i, 1)]
n, d = 0, 1
for i in range(100, 0, -1):
n, d = next_expansion(n, d, e_sequence[i - 1])
s = sum([int(l) for l in str(n)])
return s
if __name__ == "__main__":
print("e065.py: " + str(euler_065()))
assert(euler_065() == 0)
assert(euler_065() == 272)

View File

@ -1,8 +1,97 @@
import math
from e057 import add_fractions
def get_floor_sqrt(n):
return math.floor(math.sqrt(n))
def next_expansion_1(current_a, current_nominator,
current_denominator, original_number):
cn = current_nominator
cd = current_denominator
cn, cd = cd, (original_number - cd * cd) // cn
next_a = math.floor((math.sqrt(original_number) + cn) // cd)
cn = cn - next_a * cd
cn *= -1
return next_a, cn, cd
def get_continued_fraction_sequence(n):
# If number is a square number we return it.
floor_sqrt = get_floor_sqrt(n)
if n == floor_sqrt * floor_sqrt:
return ((floor_sqrt), [])
# Otherwise, we calculate the next expansion till we
# encounter a step a second time.
a = floor_sqrt
cn = a
cd = 1
sequence = []
previous_steps = []
while not (a, cn, cd) in previous_steps:
# print("a: {} cn: {} cd: {}".format(a, cn, cd))
previous_steps.append((a, cn, cd))
a, cn, cd = next_expansion_1(a, cd, cn, n)
sequence.append(a)
sequence.pop()
return ((floor_sqrt), sequence)
def next_expansion_2(previous_numerator, previous_denumerator, value):
if previous_numerator == 0:
return (value, 1)
return add_fractions(previous_denumerator, previous_numerator, value, 1)
def get_fractions(n, x):
# print("get_fractions(n={}, x={})".format(n, x))
# Get sequence of a_x
first_value, sequence = get_continued_fraction_sequence(n)
sequence = [first_value] + math.ceil(x / len(sequence)) * sequence
sequence = sequence[:x + 1]
sequence = sequence[::-1]
n, d = 0, 1
for s in sequence:
n, d = next_expansion_2(n, d, s)
return (n, d)
def get_minimal_solution(d):
for i in range(0, 100):
x, y = get_fractions(d, i)
if x * x - d * y * y == 1:
return((x, y))
def is_square(n):
return math.sqrt(n).is_integer()
def euler_066():
return 0
# XXX: This seems really long and complicated. We can do better.
x_max = 0
d_max = 0
for d in range(2, 1001):
if is_square(d):
continue
x, y = get_minimal_solution(d)
if x > x_max:
x_max = x
d_max = d
print("d: {} x: {}".format(d_max, x_max))
s = d_max
return s
if __name__ == "__main__":
print("e066.py: " + str(euler_066()))
assert(euler_066() == 0)
assert(euler_066() == 661)

View File

@ -1,5 +1,5 @@
def euler_068():
# XXX: continue here
return 0

View File

@ -196,7 +196,13 @@ def permutations(iterable):
def gcd(a, b):
""" Returns the greatest commond divisor of a and b. """
if b == 0:
return a
return gcd(b, a % b)
while a % b != 0:
a, b = b, a % b
return b
def get_digit_count(n):
"""
Returns the number of digits for n.
"""
return len(str(n))

View File

@ -13,6 +13,7 @@ try:
from .lib_misc import proper_divisors, sum_proper_divisors
from .lib_misc import permutations
from .lib_misc import gcd
from .lib_misc import get_digit_count
except ModuleNotFoundError:
from lib_misc import is_palindrome_integer
from lib_misc import is_palindrome_string
@ -27,6 +28,7 @@ except ModuleNotFoundError:
from lib_misc import proper_divisors, sum_proper_divisors
from lib_misc import permutations
from lib_misc import gcd
from lib_misc import get_digit_count
class TestPrimeMethods(unittest.TestCase):
@ -131,6 +133,10 @@ class TestPrimeMethods(unittest.TestCase):
self.assertEqual(gcd(15, 6), 3)
self.assertEqual(gcd(6, 15), 3)
def test_get_digit_count(self):
self.assertEqual(get_digit_count(1), 1)
self.assertEqual(get_digit_count(1234567890), 10)
if __name__ == '__main__':
unittest.main()