From 0da5ceafd9867889064e0de59263050e73608625 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 20 Feb 2020 18:03:31 +0700 Subject: [PATCH 01/10] added doctests in modular_exponential.py --- dynamic_programming/coin_change.py | 17 +++++++++++++++-- linear_algebra/src/lib.py | 22 ++++++++++++---------- maths/modular_exponential.py | 22 +++++++++++++++++++--- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/dynamic_programming/coin_change.py b/dynamic_programming/coin_change.py index a85d8e08dbb1..2d7106f0cc6f 100644 --- a/dynamic_programming/coin_change.py +++ b/dynamic_programming/coin_change.py @@ -8,6 +8,18 @@ def dp_count(S, m, n): + """ + >>> dp_count([1, 2, 3], 3, 4) + 4 + >>> dp_count([1, 2, 3], 3, 7) + 8 + >>> dp_count([2, 5, 3, 6], 4, 10) + 5 + >>> dp_count([10], 1, 99) + 0 + >>> dp_count([4, 5, 6], 3, 0) + 1 + """ # table[i] represents the number of ways to get to amount i table = [0] * (n + 1) @@ -26,5 +38,6 @@ def dp_count(S, m, n): if __name__ == "__main__": - print(dp_count([1, 2, 3], 3, 4)) # answer 4 - print(dp_count([2, 5, 3, 6], 4, 10)) # answer 5 + import doctest + + doctest.testmod() diff --git a/linear_algebra/src/lib.py b/linear_algebra/src/lib.py index 5ce0f696ad71..bf9e0d302a89 100644 --- a/linear_algebra/src/lib.py +++ b/linear_algebra/src/lib.py @@ -27,7 +27,7 @@ class Vector(object): """ - This class represents a vector of arbitray size. + This class represents a vector of arbitrary size. You need to give the vector components. Overview about the methods: @@ -37,7 +37,7 @@ class Vector(object): __str__() : toString method component(i : int): gets the i-th component (start by 0) __len__() : gets the size of the vector (number of components) - euclidLength() : returns the eulidean length of the vector. + euclidLength() : returns the euclidean length of the vector. operator + : vector addition operator - : vector subtraction operator * : scalar multiplication and dot product @@ -46,11 +46,13 @@ class Vector(object): TODO: compare-operator """ - def __init__(self, components=[]): + def __init__(self, components=None): """ input: components or nothing simple constructor for init the vector """ + if components is None: + components = [] self.__components = list(components) def set(self, components): @@ -86,9 +88,9 @@ def __len__(self): """ return len(self.__components) - def eulidLength(self): + def euclidLength(self): """ - returns the eulidean length of the vector + returns the euclidean length of the vector """ summe = 0 for c in self.__components: @@ -112,7 +114,7 @@ def __sub__(self, other): """ input: other vector assumes: other vector has the same size - returns a new vector that represents the differenz. + returns a new vector that represents the difference. """ size = len(self) if size == len(other): @@ -136,7 +138,7 @@ def __mul__(self, other): summe += self.__components[i] * other.component(i) return summe else: # error case - raise Exception("invalide operand!") + raise Exception("invalid operand!") def copy(self): """ @@ -223,7 +225,7 @@ class Matrix(object): def __init__(self, matrix, w, h): """ - simple constructor for initialzes + simple constructor for initializing the matrix with components. """ self.__matrix = matrix @@ -249,7 +251,7 @@ def changeComponent(self, x, y, value): """ changes the x-y component of this matrix """ - if x >= 0 and x < self.__height and y >= 0 and y < self.__width: + if 0 <= x < self.__height and 0 <= y < self.__width: self.__matrix[x][y] = value else: raise Exception("changeComponent: indices out of bounds") @@ -258,7 +260,7 @@ def component(self, x, y): """ returns the specified (x,y) component """ - if x >= 0 and x < self.__height and y >= 0 and y < self.__width: + if 0 <= x < self.__height and 0 <= y < self.__width: return self.__matrix[x][y] else: raise Exception("changeComponent: indices out of bounds") diff --git a/maths/modular_exponential.py b/maths/modular_exponential.py index 8715e17147ff..5a3493669a19 100644 --- a/maths/modular_exponential.py +++ b/maths/modular_exponential.py @@ -1,8 +1,19 @@ -"""Modular Exponential.""" - +""" + Modular Exponential. + Modular exponentiation is a type of exponentiation performed over a modulus. +""" +"""Calculate Modular Exponential.""" def modular_exponential(base, power, mod): - """Calculate Modular Exponential.""" + """ + >>> modular_exponential(5, 0, 10) + 1 + >>> modular_exponential(2, 8, 7) + 4 + >>> modular_exponential(3, -2, 9) + -1 + """ + if power < 0: return -1 base %= mod @@ -13,6 +24,7 @@ def modular_exponential(base, power, mod): result = (result * base) % mod power = power >> 1 base = (base * base) % mod + return result @@ -22,4 +34,8 @@ def main(): if __name__ == "__main__": + import doctest + + doctest.testmod() + main() From 4183239405ad4c20b293774ab74a597c082ff714 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 20 Feb 2020 18:11:35 +0700 Subject: [PATCH 02/10] added doctests in modular_exponential.py --- maths/modular_exponential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/modular_exponential.py b/maths/modular_exponential.py index 5a3493669a19..0fd35d65b780 100644 --- a/maths/modular_exponential.py +++ b/maths/modular_exponential.py @@ -4,7 +4,7 @@ """ """Calculate Modular Exponential.""" -def modular_exponential(base, power, mod): +def modular_exponential(base : int, power : int, mod : int): """ >>> modular_exponential(5, 0, 10) 1 From 3856fa064d97ee70cdfd0db0dfdeabc4db1474e2 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 20 Feb 2020 18:19:59 +0700 Subject: [PATCH 03/10] added URL link --- maths/modular_exponential.py | 1 + 1 file changed, 1 insertion(+) diff --git a/maths/modular_exponential.py b/maths/modular_exponential.py index 0fd35d65b780..91fa0e462a49 100644 --- a/maths/modular_exponential.py +++ b/maths/modular_exponential.py @@ -1,6 +1,7 @@ """ Modular Exponential. Modular exponentiation is a type of exponentiation performed over a modulus. + For more explanation, please check https://en.wikipedia.org/wiki/Modular_exponentiation """ """Calculate Modular Exponential.""" From e3fa97fbb45bf26f3bbbc226bfa4ef9c6744e3e0 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 1 Oct 2020 08:42:16 +0700 Subject: [PATCH 04/10] Add project euler problem_49 solution --- project_euler/problem_49/__init__.py | 0 project_euler/problem_49/sol1.py | 131 +++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 project_euler/problem_49/__init__.py create mode 100644 project_euler/problem_49/sol1.py 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..92138da9a3fc --- /dev/null +++ b/project_euler/problem_49/sol1.py @@ -0,0 +1,131 @@ +""" +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. +""" + +from math import sqrt, floor +from itertools import permutations + + +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 + """ + + l, r = 0, len(prime_list) - 1 + while l <= r: + m = (l + r) // 2 + if prime_list[m] == target: + return True + elif prime_list[m] < target: + l = m + 1 + else: + r = 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 [x for x in answer][1] + + +if __name__ == "__main__": + print(solution()) From 7ef4facc2398022097dbc9481888a7731244f585 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 1 Oct 2020 08:55:56 +0700 Subject: [PATCH 05/10] Add project euler problem_50 solution --- project_euler/problem_50/__init__.py | 0 project_euler/problem_50/sol1.py | 100 +++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 project_euler/problem_50/__init__.py create mode 100644 project_euler/problem_50/sol1.py 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..92212091ca85 --- /dev/null +++ b/project_euler/problem_50/sol1.py @@ -0,0 +1,100 @@ +""" +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. +""" + +from math import sqrt, floor + + +def is_prime(number: int) -> bool: + """ + function to check wether 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()) From d30669bc5a92fb7d6d3ad56cf7ea3e9571597c98 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 1 Oct 2020 01:56:54 +0000 Subject: [PATCH 06/10] fixup! Format Python code with psf/black push --- project_euler/problem_49/sol1.py | 12 ++++++++---- project_euler/problem_50/sol1.py | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index 92138da9a3fc..4d42e56276f9 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -26,8 +26,8 @@ 3 nested loops since we know the answer will be 12 digits. """ -from math import sqrt, floor from itertools import permutations +from math import floor, sqrt def is_prime(number: int) -> bool: @@ -107,10 +107,14 @@ def solution(): 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: + 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]])) + sorted([candidate[i], candidate[j], candidate[k]]) + ) found = True if found: diff --git a/project_euler/problem_50/sol1.py b/project_euler/problem_50/sol1.py index 92212091ca85..71bb931898ff 100644 --- a/project_euler/problem_50/sol1.py +++ b/project_euler/problem_50/sol1.py @@ -25,7 +25,7 @@ Then, use sliding window to get the answer. """ -from math import sqrt, floor +from math import floor, sqrt def is_prime(number: int) -> bool: @@ -56,20 +56,20 @@ def solution(): 997651 """ - prime_list = [2] + [x for x in range(3, 10**6, 2) if is_prime(x)] + 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: + 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: + if prime_list[i] < 10 ** 6: upper_limit_idx = i else: break @@ -96,5 +96,5 @@ def solution(): return answer -if __name__ == '__main__': +if __name__ == "__main__": print(solution()) From a0a2941678b55231e1698abfdb0cdd68d551f12e Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 1 Oct 2020 08:59:03 +0700 Subject: [PATCH 07/10] Fix typo --- project_euler/problem_50/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_50/sol1.py b/project_euler/problem_50/sol1.py index 92212091ca85..6bee88adebb8 100644 --- a/project_euler/problem_50/sol1.py +++ b/project_euler/problem_50/sol1.py @@ -30,7 +30,7 @@ def is_prime(number: int) -> bool: """ - function to check wether a number is a prime or not. + function to check whether a number is a prime or not. >>> is_prime(2) True >>> is_prime(6) From 6dc7bef9dcc93f003675733025269f208e84b845 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 1 Oct 2020 02:01:39 +0000 Subject: [PATCH 08/10] updating DIRECTORY.md --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) 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 From 581c44d937d8dd20edca38dc4d116226f5ebe458 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 1 Oct 2020 09:13:42 +0700 Subject: [PATCH 09/10] Fix flake8 errors --- project_euler/problem_49/sol1.py | 16 ++++++++-------- project_euler/problem_50/sol1.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index 4d42e56276f9..d634110f3f19 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -1,3 +1,6 @@ +from itertools import permutations +from math import floor, sqrt + """ Prime permutations @@ -26,9 +29,6 @@ 3 nested loops since we know the answer will be 12 digits. """ -from itertools import permutations -from math import floor, sqrt - def is_prime(number: int) -> bool: """ @@ -60,15 +60,15 @@ def search(target: int, prime_list: list) -> bool: False """ - l, r = 0, len(prime_list) - 1 - while l <= r: - m = (l + r) // 2 + 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: - l = m + 1 + left = m + 1 else: - r = m - 1 + right = m - 1 return False diff --git a/project_euler/problem_50/sol1.py b/project_euler/problem_50/sol1.py index d1d00321cd74..c7f21a3baf9c 100644 --- a/project_euler/problem_50/sol1.py +++ b/project_euler/problem_50/sol1.py @@ -1,3 +1,5 @@ +from math import floor, sqrt + """ Consecutive prime sum @@ -25,8 +27,6 @@ Then, use sliding window to get the answer. """ -from math import floor, sqrt - def is_prime(number: int) -> bool: """ From ed5d00eb55967d054e07f6e8eee15c3ded11bb58 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 1 Oct 2020 09:24:17 +0700 Subject: [PATCH 10/10] Fix return type --- project_euler/problem_49/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index d634110f3f19..17987026b257 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -128,7 +128,7 @@ def solution(): for seq in passed: answer.add("".join(list(map(str, seq)))) - return [x for x in answer][1] + return max(map(int, [x for x in answer])) if __name__ == "__main__":