From 0da5ceafd9867889064e0de59263050e73608625 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Thu, 20 Feb 2020 18:03:31 +0700 Subject: [PATCH 1/9] 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 2/9] 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 3/9] 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 56990e6b178fa2f91df89a08ff7870fe7253838c Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 3 Oct 2020 15:17:38 +0000 Subject: [PATCH 4/9] updating DIRECTORY.md --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 37eaadb89786..9e33eb6c00ba 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -547,6 +547,8 @@ * Problem 11 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_11/sol1.py) * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_11/sol2.py) + * Problem 112 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_112/sol1.py) * Problem 12 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_12/sol1.py) * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_12/sol2.py) From f13bba51469d0f12725b27cfad87e380a5aaaf12 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Sat, 3 Oct 2020 22:23:14 +0700 Subject: [PATCH 5/9] Add problem 49 solution --- project_euler/problem_49/__init__.py | 0 project_euler/problem_49/sol1.py | 135 +++++++++++++++++++++++++++ 2 files changed, 135 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..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()) From b92d14f9a9918572f8fc36dea51812c0012985f2 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 3 Oct 2020 15:24:09 +0000 Subject: [PATCH 6/9] updating DIRECTORY.md --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 9e33eb6c00ba..b00a203391a8 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -633,6 +633,8 @@ * [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 52 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_52/sol1.py) * Problem 53 From c748482560be8d9e65be5d647c10ea505a179459 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Sun, 4 Oct 2020 21:35:14 +0700 Subject: [PATCH 7/9] Fix several mistakes These fixes are intended to follow the CONTRIBUTING.md --- project_euler/problem_49/sol1.py | 37 ++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index 17987026b257..336ef090b095 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -15,9 +15,7 @@ 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 @@ -27,6 +25,7 @@ After that, bruteforce all passed candidates sequences using 3 nested loops since we know the answer will be 12 digits. +The bruteforce of this solution will be about 1 sec. """ @@ -39,6 +38,10 @@ def is_prime(number: int) -> bool: False >>> is_prime(1) False + >>> is_prime(-800) + False + >>> is_prime(104729) + True """ if number < 2: @@ -58,17 +61,19 @@ def search(target: int, prime_list: list) -> bool: True >>> search(4, [1, 2, 3]) False + >>> search(101, list(range(-100, 100))) + False """ left, right = 0, len(prime_list) - 1 while left <= right: - m = (left + right) // 2 - if prime_list[m] == target: + middle = (left + right) // 2 + if prime_list[middle] == target: return True - elif prime_list[m] < target: - left = m + 1 + elif prime_list[middle] < target: + left = middle + 1 else: - right = m - 1 + right = middle - 1 return False @@ -82,18 +87,18 @@ def solution(): 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)))) + for number in prime_list: + perm = list(permutations(list(str(number)))) tmp_numbers = [] - for i in range(len(perm)): - p = int("".join(list(perm[i]))) + for prime_member in perm: + prime = int("".join(list(prime_member))) - if p % 2 == 0: + if prime % 2 == 0: continue - if search(p, prime_list): - tmp_numbers.append(p) + if search(prime, prime_list): + tmp_numbers.append(prime) tmp_numbers.sort() if len(tmp_numbers) >= 3: @@ -126,9 +131,9 @@ def solution(): answer = set() for seq in passed: - answer.add("".join(list(map(str, seq)))) + answer.add("".join([str(i) for i in seq])) - return max(map(int, [x for x in answer])) + return max([int(x) for x in answer]) if __name__ == "__main__": From 771c7362d6f291608242c7e7d68eb39b84933a20 Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Mon, 5 Oct 2020 08:05:35 +0700 Subject: [PATCH 8/9] Move the import statements lower --- project_euler/problem_49/sol1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index 336ef090b095..183da7c8232f 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -1,6 +1,3 @@ -from itertools import permutations -from math import floor, sqrt - """ Prime permutations @@ -28,6 +25,9 @@ The bruteforce of this solution will be about 1 sec. """ +from itertools import permutations +from math import floor, sqrt + def is_prime(number: int) -> bool: """ From 05c9a3607e59223cd75e87ecf7335fbe971bbc5b Mon Sep 17 00:00:00 2001 From: Iqrar Agalosi Nureyza Date: Mon, 5 Oct 2020 09:51:14 +0700 Subject: [PATCH 9/9] Update project_euler/problem_49/sol1.py Co-authored-by: Dhruv --- project_euler/problem_49/sol1.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/project_euler/problem_49/sol1.py b/project_euler/problem_49/sol1.py index 183da7c8232f..6c3d69ad0d11 100644 --- a/project_euler/problem_49/sol1.py +++ b/project_euler/problem_49/sol1.py @@ -88,11 +88,10 @@ def solution(): candidates = [] for number in prime_list: - perm = list(permutations(list(str(number)))) tmp_numbers = [] - for prime_member in perm: - prime = int("".join(list(prime_member))) + for prime_member in permutations(list(str(number))): + prime = int("".join(prime_member)) if prime % 2 == 0: continue