Finished existing ipython solutions to python. Ready to continue in pure python.
parent
c624e6ac52
commit
45e0cd8a78
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
def euler_068():
|
||||
# XXX: continue here
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue