Skip to content

Commit 87c8c90

Browse files
authored
Merge branch 'master' into master
2 parents fffb37e + 68473af commit 87c8c90

22 files changed

+163
-57
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ We want your work to be readable by others; therefore, we encourage you to note
159159
starting_value = int(input("Please enter a starting value: ").strip())
160160
```
161161

162-
The use of [Python type hints](https://docs.python.org/3/library/typing.html) is encouraged for function parameters and return values. Our automated testing will run [mypy](http://mypy-lang.org) so run that locally before making your submission.
162+
The use of [Python type hints](https://docs.python.org/3/library/typing.html) is encouraged for function parameters and return values. Our automated testing will run [mypy](https://mypy-lang.org) so run that locally before making your submission.
163163

164164
```python
165165
def sum_ab(a: int, b: int) -> int:

DIRECTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@
469469

470470
## Geometry
471471
* [Geometry](geometry/geometry.py)
472+
* [Graham Scan](geometry/graham_scan.py)
473+
* [Jarvis March](geometry/jarvis_march.py)
474+
* Tests
475+
* [Test Graham Scan](geometry/tests/test_graham_scan.py)
476+
* [Test Jarvis March](geometry/tests/test_jarvis_march.py)
472477

473478
## Graphics
474479
* [Bezier Curve](graphics/bezier_curve.py)
@@ -981,6 +986,7 @@
981986
* [Sol2](project_euler/problem_014/sol2.py)
982987
* Problem 015
983988
* [Sol1](project_euler/problem_015/sol1.py)
989+
* [Sol2](project_euler/problem_015/sol2.py)
984990
* Problem 016
985991
* [Sol1](project_euler/problem_016/sol1.py)
986992
* [Sol2](project_euler/problem_016/sol2.py)

backtracking/coloring.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ def color(graph: list[list[int]], max_colors: int) -> list[int]:
104104
>>> max_colors = 2
105105
>>> color(graph, max_colors)
106106
[]
107+
>>> color([], 2) # empty graph
108+
[]
109+
>>> color([[0]], 1) # single node, 1 color
110+
[0]
111+
>>> color([[0, 1], [1, 0]], 1) # 2 nodes, 1 color (impossible)
112+
[]
113+
>>> color([[0, 1], [1, 0]], 2) # 2 nodes, 2 colors (possible)
114+
[0, 1]
107115
"""
108116
colored_vertices = [-1] * len(graph)
109117

backtracking/generate_parentheses.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def generate_parenthesis(n: int) -> list[str]:
6464
Example 2:
6565
>>> generate_parenthesis(1)
6666
['()']
67+
68+
Example 3:
69+
>>> generate_parenthesis(0)
70+
['']
6771
"""
6872

6973
result: list[str] = []

backtracking/generate_parentheses_iterative.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
def generate_parentheses_iterative(length: int) -> list:
1+
def generate_parentheses_iterative(length: int) -> list[str]:
22
"""
33
Generate all valid combinations of parentheses (Iterative Approach).
44
55
The algorithm works as follows:
66
1. Initialize an empty list to store the combinations.
77
2. Initialize a stack to keep track of partial combinations.
8-
3. Start with empty string and push it onstack along with the counts of '(' and ')'.
8+
3. Start with empty string and push it on stack along with
9+
the counts of '(' and ')'.
910
4. While the stack is not empty:
1011
a. Pop a partial combination and its open and close counts from the stack.
1112
b. If the combination length is equal to 2*length, add it to the result.
@@ -34,8 +35,11 @@ def generate_parentheses_iterative(length: int) -> list:
3435
>>> generate_parentheses_iterative(0)
3536
['']
3637
"""
37-
result = []
38-
stack = []
38+
if length == 0:
39+
return [""]
40+
41+
result: list[str] = []
42+
stack: list[tuple[str, int, int]] = []
3943

4044
# Each element in stack is a tuple (current_combination, open_count, close_count)
4145
stack.append(("", 0, 0))
@@ -45,6 +49,7 @@ def generate_parentheses_iterative(length: int) -> list:
4549

4650
if len(current_combination) == 2 * length:
4751
result.append(current_combination)
52+
continue
4853

4954
if open_count < length:
5055
stack.append((current_combination + "(", open_count + 1, close_count))

backtracking/n_queens.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ def is_safe(board: list[list[int]], row: int, column: int) -> bool:
3333
False
3434
>>> is_safe([[0, 0, 1], [0, 0, 0], [0, 0, 0]], 1, 1)
3535
False
36+
>>> is_safe([[1, 0, 0], [0, 0, 0], [0, 0, 0]], 1, 2)
37+
True
38+
>>> is_safe([[1, 0, 0], [0, 0, 0], [0, 0, 0]], 2, 1)
39+
True
40+
>>> is_safe([[0, 0, 0], [1, 0, 0], [0, 0, 0]], 0, 2)
41+
True
42+
>>> is_safe([[0, 0, 0], [1, 0, 0], [0, 0, 0]], 2, 2)
43+
True
3644
"""
3745

3846
n = len(board) # Size of the board

backtracking/word_break.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ def word_break(input_string: str, word_dict: set[str]) -> bool:
6666
6767
>>> word_break("catsandog", {"cats", "dog", "sand", "and", "cat"})
6868
False
69+
70+
>>> word_break("applepenapple", {})
71+
False
6972
"""
7073

7174
return backtrack(input_string, word_dict, 0)

geodesy/lamberts_ellipsoidal_distance.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@ def lamberts_ellipsoidal_distance(
3232
Returns:
3333
geographical distance between two points in metres
3434
35+
>>> lamberts_ellipsoidal_distance(100, 0, 0, 0)
36+
Traceback (most recent call last):
37+
...
38+
ValueError: Latitude must be between -90 and 90 degrees
39+
40+
>>> lamberts_ellipsoidal_distance(0, 0, -100, 0)
41+
Traceback (most recent call last):
42+
...
43+
ValueError: Latitude must be between -90 and 90 degrees
44+
45+
>>> lamberts_ellipsoidal_distance(0, 200, 0, 0)
46+
Traceback (most recent call last):
47+
...
48+
ValueError: Longitude must be between -180 and 180 degrees
49+
50+
>>> lamberts_ellipsoidal_distance(0, 0, 0, -200)
51+
Traceback (most recent call last):
52+
...
53+
ValueError: Longitude must be between -180 and 180 degrees
54+
3555
>>> from collections import namedtuple
3656
>>> point_2d = namedtuple("point_2d", "lat lon")
3757
>>> SAN_FRANCISCO = point_2d(37.774856, -122.424227)
@@ -46,6 +66,14 @@ def lamberts_ellipsoidal_distance(
4666
'9,737,326 meters'
4767
"""
4868

69+
# Validate latitude values
70+
if not -90 <= lat1 <= 90 or not -90 <= lat2 <= 90:
71+
raise ValueError("Latitude must be between -90 and 90 degrees")
72+
73+
# Validate longitude values
74+
if not -180 <= lon1 <= 180 or not -180 <= lon2 <= 180:
75+
raise ValueError("Longitude must be between -180 and 180 degrees")
76+
4977
# CONSTANTS per WGS84 https://en.wikipedia.org/wiki/World_Geodetic_System
5078
# Distance in metres(m)
5179
# Equation Parameters

maths/area.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,6 @@ def area_reg_polygon(sides: int, length: float) -> float:
552552
length of a side"
553553
)
554554
return (sides * length**2) / (4 * tan(pi / sides))
555-
return (sides * length**2) / (4 * tan(pi / sides))
556555

557556

558557
if __name__ == "__main__":

maths/factorial.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,21 @@ def factorial_recursive(n: int) -> int:
4141
https://en.wikipedia.org/wiki/Factorial
4242
4343
>>> import math
44-
>>> all(factorial(i) == math.factorial(i) for i in range(20))
44+
>>> all(factorial_recursive(i) == math.factorial(i) for i in range(20))
4545
True
46-
>>> factorial(0.1)
46+
>>> factorial_recursive(0.1)
4747
Traceback (most recent call last):
4848
...
49-
ValueError: factorial() only accepts integral values
50-
>>> factorial(-1)
49+
ValueError: factorial_recursive() only accepts integral values
50+
>>> factorial_recursive(-1)
5151
Traceback (most recent call last):
5252
...
53-
ValueError: factorial() not defined for negative values
53+
ValueError: factorial_recursive() not defined for negative values
5454
"""
5555
if not isinstance(n, int):
56-
raise ValueError("factorial() only accepts integral values")
56+
raise ValueError("factorial_recursive() only accepts integral values")
5757
if n < 0:
58-
raise ValueError("factorial() not defined for negative values")
58+
raise ValueError("factorial_recursive() not defined for negative values")
5959
return 1 if n in {0, 1} else n * factorial_recursive(n - 1)
6060

6161

0 commit comments

Comments
 (0)