diff --git a/DIRECTORY.md b/DIRECTORY.md index 37eaadb89786..9e8f2539a8c0 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -631,6 +631,10 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_47/sol1.py) * Problem 48 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_48/sol1.py) + * Problem 49 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_49/sol1.py) + * Problem 50 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_50/sol1.py) * Problem 52 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_52/sol1.py) * Problem 53 diff --git a/project_euler/problem_49/__init__.py b/project_euler/problem_49/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py new file mode 100644 index 000000000000..17987026b257 --- /dev/null +++ b/project_euler/problem_49/sol1.py @@ -0,0 +1,135 @@ +from itertools import permutations +from math import floor, sqrt + +""" +Prime permutations + +Problem 49 + +The arithmetic sequence, 1487, 4817, 8147, in which each of +the terms increases by 3330, is unusual in two ways: +(i) each of the three terms are prime, +(ii) each of the 4-digit numbers are permutations of one another. + +There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, +exhibiting this property, but there is one other 4-digit increasing sequence. + +What 12-digit number do you form by concatenating the three terms in this sequence? +""" + +""" +Solution: + +First, we need to generate all 4 digits prime numbers. Then greedy +all of them and use permutation to form new numbers. Use binary search +to check if the permutated numbers is in our prime list and include +them in a candidate list. + +After that, bruteforce all passed candidates sequences using +3 nested loops since we know the answer will be 12 digits. +""" + + +def is_prime(number: int) -> bool: + """ + function to check whether the number is prime or not. + >>> is_prime(2) + True + >>> is_prime(6) + False + >>> is_prime(1) + False + """ + + if number < 2: + return False + + for i in range(2, floor(sqrt(number)) + 1): + if number % i == 0: + return False + + return True + + +def search(target: int, prime_list: list) -> bool: + """ + function to search a number in a list using Binary Search. + >>> search(3, [1, 2, 3]) + True + >>> search(4, [1, 2, 3]) + False + """ + + left, right = 0, len(prime_list) - 1 + while left <= right: + m = (left + right) // 2 + if prime_list[m] == target: + return True + elif prime_list[m] < target: + left = m + 1 + else: + right = m - 1 + + return False + + +def solution(): + """ + Return the solution of the problem. + >>> solution() + 296962999629 + """ + prime_list = [n for n in range(1001, 10000, 2) if is_prime(n)] + candidates = [] + + for x in prime_list: + perm = list(permutations(list(str(x)))) + tmp_numbers = [] + + for i in range(len(perm)): + p = int("".join(list(perm[i]))) + + if p % 2 == 0: + continue + + if search(p, prime_list): + tmp_numbers.append(p) + + tmp_numbers.sort() + if len(tmp_numbers) >= 3: + candidates.append(tmp_numbers) + + passed = [] + for candidate in candidates: + length = len(candidate) + found = False + + for i in range(length): + for j in range(i + 1, length): + for k in range(j + 1, length): + if ( + abs(candidate[i] - candidate[j]) + == abs(candidate[j] - candidate[k]) + and len(set([candidate[i], candidate[j], candidate[k]])) == 3 + ): + passed.append( + sorted([candidate[i], candidate[j], candidate[k]]) + ) + found = True + + if found: + break + if found: + break + if found: + break + + answer = set() + for seq in passed: + answer.add("".join(list(map(str, seq)))) + + return max(map(int, [x for x in answer])) + + +if __name__ == "__main__": + print(solution()) diff --git a/project_euler/problem_50/__init__.py b/project_euler/problem_50/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_50/sol1.py b/project_euler/problem_50/sol1.py new file mode 100644 index 000000000000..c7f21a3baf9c --- /dev/null +++ b/project_euler/problem_50/sol1.py @@ -0,0 +1,100 @@ +from math import floor, sqrt + +""" +Consecutive prime sum + +Problem 50 + +The prime 41, can be written as the sum of six consecutive primes: + +41 = 2 + 3 + 5 + 7 + 11 + 13 + +This is the longest sum of consecutive primes that adds to +a prime below one-hundred. + +The longest sum of consecutive primes below one-thousand that adds to a prime, +contains 21 terms, and is equal to 953. + +Which prime, below one-million, can be written as the sum of +the most consecutive primes? +""" + +""" +Solution: + +First of all, we need to generate all prime numbers +from 2 to the closest prime number with 1000000. +Then, use sliding window to get the answer. +""" + + +def is_prime(number: int) -> bool: + """ + function to check whether a number is a prime or not. + >>> is_prime(2) + True + >>> is_prime(6) + False + >>> is_prime(1) + False + """ + + if number < 2: + return False + + for n in range(2, floor(sqrt(number)) + 1): + if number % n == 0: + return False + + return True + + +def solution(): + """ + Return the problem solution. + >>> solution() + 997651 + """ + + prime_list = [2] + [x for x in range(3, 10 ** 6, 2) if is_prime(x)] + + cumulative_sum = [] + tmp = 0 + for x in prime_list: + tmp += x + if tmp < 10 ** 6: + cumulative_sum.append(tmp) + else: + break + + upper_limit_idx = 0 + for i in range(len(prime_list)): + if prime_list[i] < 10 ** 6: + upper_limit_idx = i + else: + break + + max_count = -1 + answer = 0 + for number in reversed(cumulative_sum): + count_prime = cumulative_sum.index(number) + 1 + + if not is_prime(number): + tmp = number + + for i in range(upper_limit_idx): + count_prime -= 1 + tmp -= prime_list[i] + + if is_prime(tmp) or tmp < 0: + break + + if max_count < count_prime: + max_count = count_prime + answer = tmp + + return answer + + +if __name__ == "__main__": + print(solution())