From ac2e5dfa55b33482f440de0e9a1a1c875163de7e Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 21:07:33 -0500 Subject: [PATCH 01/10] Addition to the Geometry Folder with Triangle that calculates the different triangle centers --- geometry/Triangle.py | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 geometry/Triangle.py diff --git a/geometry/Triangle.py b/geometry/Triangle.py new file mode 100644 index 000000000000..88bad9395ef9 --- /dev/null +++ b/geometry/Triangle.py @@ -0,0 +1,126 @@ +from __future__ import annotations +import math +from numpy import array, linalg +from dataclasses import dataclass, field + +# Define a Point on a 2D normalized orthoganal euclidian grid + + +@dataclass +class Point: + """ + A point defined by 2 floats representing a length on a normalized + orthoganal coordinate system + default coordinate is the origin + + >>> Point(-1.0, 0.0) + Point(x=-1.0, y=0.0) + + """ + + x: float = 0.0 + y: float = 0.0 + + def __post_init__(self) -> None: + if not isinstance(self.x, (int, float)): + raise TypeError("x must be an int or float numeric value") + if not isinstance(self.y, (int, float)): + raise TypeError("y must be an int or float numeric value") + + +@dataclass +class Triangle: + """ + A 3 point Triangle on a 2D normalized orthoganal euclidian grid + + >>> p1 = Point(-1.0,0.0) + >>> p2 = Point(1.0,0.0) + >>> p3 = Point(0.0,1.0) + >>> Triangle(p1, p2, p3) + + Triangle(v1 = Point(-1.0,0.0), v2 = Point(1.0,0.0), v3 = Point(0.0,1.0)) + """ + + v1: Point = field(default_factory=Point) + v2: Point = field(default_factory=Point) + v3: Point = field(default_factory=Point) + circum: Point = field(default_factory=Point) + incen: Point = field(default_factory=Point) + ortho: Point = field(default_factory=Point) + + def __post_init__(self) -> None: + # Check for valid arguments + if ( + not isinstance(self.v1, Point) + or not isinstance(self.v2, Point) + or not isinstance(self.v3, Point) + ): + raise TypeError("All 3 arguements should be Point Objects") + # Check for 3 unique points + if self.v1 == self.v2 or self.v1 == self.v3 or self.v2 == self.v3: + raise TypeError("All 3 arguements should be unique") + # Check for linearity + if self.v1.x == self.v2.x: + if self.v3.y == self.v2.y: + raise TypeError("One or more arguments are redundant") + m = (self.v1.y - self.v2.y) / (self.v1.x - self.v2.x) + yb = self.v1.y - m * self.v1.x + if self.v3.y == m * self.v3.x + yb: + raise TypeError("One or more arguments are redundant") + + # Circumcenter + @property + def circumcenter(self) -> Point: + m_0 = array( + [ + [self.v1.x, self.v1.y, 1], + [self.v2.x, self.v2.y, 1], + [self.v3.x, self.v3.y, 1], + ] + ) + m_1 = array( + [ + [self.v1.x**2 + self.v1.y**2, self.v1.y, 1], + [self.v2.x**2 + self.v2.y**2, self.v2.y, 1], + [self.v3.x**2 + self.v3.y**2, self.v3.y, 1], + ] + ) + m_2 = array( + [ + [self.v1.x**2 + self.v1.y**2, self.v1.x, 1], + [self.v2.x**2 + self.v2.y**2, self.v2.x, 1], + [self.v3.x**2 + self.v3.y**2, self.v3.x, 1], + ] + ) + a = linalg.det(m_0) + bx = -linalg.det(m_1) + by = linalg.det(m_2) + self.circum.x = -bx / (2 * a) + self.circum.y = -by / (2 * a) + return self.circum + + # Incenter + @property + def incenter(self) -> Point: + a = math.sqrt((self.v2.x - self.v3.x) ** 2 + (self.v2.y - self.v3.y) ** 2) + b = math.sqrt((self.v1.x - self.v3.x) ** 2 + (self.v1.y - self.v3.y) ** 2) + c = math.sqrt((self.v1.x - self.v2.x) ** 2 + (self.v1.y - self.v2.y) ** 2) + self.incen.x = (a * self.v1.x + b * self.v2.x + c * self.v3.x) / (a + b + c) + self.incen.y = (a * self.v1.y + b * self.v2.y + c * self.v3.y) / (a + b + c) + return self.incen + + # Orthocenter + @property + def orthocenter(self) -> Point: + inv_m1 = -1 / ((self.v3.y - self.v1.y) / (self.v3.x - self.v1.x)) + inv_m2 = -1 / ((self.v3.y - self.v2.y) / (self.v3.x - self.v2.x)) + m = array([[inv_m2, -1], [inv_m1, -1]]) + b = array([[inv_m2 * self.v1.x - self.v1.y], [inv_m1 * self.v2.x - self.v2.y]]) + soln = linalg.solve(m, b) + self.ortho.x = soln[0][0] + self.ortho.y = soln[1][0] + return self.ortho + + +if __name__ == "__main__": + __import__("doctest").testmod() From a1b4dd1d03005797473ef736a4adf6067bafa25a Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 21:22:26 -0500 Subject: [PATCH 02/10] Addition to the Geometry Folder with Triangle that calculates the different triangle centers --- geometry/Triangle.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/geometry/Triangle.py b/geometry/Triangle.py index 88bad9395ef9..522504cd90c8 100644 --- a/geometry/Triangle.py +++ b/geometry/Triangle.py @@ -4,6 +4,9 @@ from dataclasses import dataclass, field # Define a Point on a 2D normalized orthoganal euclidian grid +# https://mathworld.wolfram.com/Circumcenter.html +# https://mathworld.wolfram.com/Incenter.html +# https://mathworld.wolfram.com/Orthocenter.html @dataclass From d56c588fe4742ea7c2204c4cebc947ec2d0daad1 Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 21:41:06 -0500 Subject: [PATCH 03/10] Original triangle center w/fixes for automated testing --- geometry/Triangle.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/geometry/Triangle.py b/geometry/Triangle.py index 522504cd90c8..b901997a8c68 100644 --- a/geometry/Triangle.py +++ b/geometry/Triangle.py @@ -1,8 +1,10 @@ from __future__ import annotations + import math -from numpy import array, linalg from dataclasses import dataclass, field +from numpy import array, linalg + # Define a Point on a 2D normalized orthoganal euclidian grid # https://mathworld.wolfram.com/Circumcenter.html # https://mathworld.wolfram.com/Incenter.html @@ -60,7 +62,7 @@ def __post_init__(self) -> None: ): raise TypeError("All 3 arguements should be Point Objects") # Check for 3 unique points - if self.v1 == self.v2 or self.v1 == self.v3 or self.v2 == self.v3: + if self.v1 in (self.v2, self.v3): raise TypeError("All 3 arguements should be unique") # Check for linearity if self.v1.x == self.v2.x: From d92d2c9f3db6615d004c1f937fa953d40bfe058f Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 21:49:03 -0500 Subject: [PATCH 04/10] triangles, added more fixes for automated testing --- geometry/Triangle.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/geometry/Triangle.py b/geometry/Triangle.py index b901997a8c68..d86fa656cb3e 100644 --- a/geometry/Triangle.py +++ b/geometry/Triangle.py @@ -5,7 +5,7 @@ from numpy import array, linalg -# Define a Point on a 2D normalized orthoganal euclidian grid +# Define a Point on a 2D normalized orthogonal euclidean grid # https://mathworld.wolfram.com/Circumcenter.html # https://mathworld.wolfram.com/Incenter.html # https://mathworld.wolfram.com/Orthocenter.html @@ -15,7 +15,7 @@ class Point: """ A point defined by 2 floats representing a length on a normalized - orthoganal coordinate system + orthogonal coordinate system default coordinate is the origin >>> Point(-1.0, 0.0) @@ -36,7 +36,7 @@ def __post_init__(self) -> None: @dataclass class Triangle: """ - A 3 point Triangle on a 2D normalized orthoganal euclidian grid + A 3 point Triangle on a 2D normalized orthogonal euclidean grid >>> p1 = Point(-1.0,0.0) >>> p2 = Point(1.0,0.0) @@ -60,10 +60,10 @@ def __post_init__(self) -> None: or not isinstance(self.v2, Point) or not isinstance(self.v3, Point) ): - raise TypeError("All 3 arguements should be Point Objects") + raise TypeError("All 3 arguments should be Point Objects") # Check for 3 unique points if self.v1 in (self.v2, self.v3): - raise TypeError("All 3 arguements should be unique") + raise TypeError("All 3 arguments should be unique") # Check for linearity if self.v1.x == self.v2.x: if self.v3.y == self.v2.y: From 533a07fba872724054ac3d18e11fc2abc41b35e1 Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 22:06:21 -0500 Subject: [PATCH 05/10] trying to rename triangle.py --- geometry/{Triangle.py => triangle.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename geometry/{Triangle.py => triangle.py} (100%) diff --git a/geometry/Triangle.py b/geometry/triangle.py similarity index 100% rename from geometry/Triangle.py rename to geometry/triangle.py From 4e8dec460fa47b2ab5babdfc3682a88b45cdddd3 Mon Sep 17 00:00:00 2001 From: AlexB Date: Tue, 5 Dec 2023 22:20:35 -0500 Subject: [PATCH 06/10] Fixed a documentation error --- geometry/triangle.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/geometry/triangle.py b/geometry/triangle.py index d86fa656cb3e..2eb2ffa24c58 100644 --- a/geometry/triangle.py +++ b/geometry/triangle.py @@ -43,7 +43,9 @@ class Triangle: >>> p3 = Point(0.0,1.0) >>> Triangle(p1, p2, p3) - Triangle(v1 = Point(-1.0,0.0), v2 = Point(1.0,0.0), v3 = Point(0.0,1.0)) + Triangle(v1=Point(x=-1.0, y=0.0), v2=Point(x=1.0, y=0.0), v3=Point(x=0.0, y=1.0), + circum=Point(x=0.0, y=0.0), incen=Point(x=0.0, y=0.0), + ortho=Point(x=0.0, y=0.0)) """ v1: Point = field(default_factory=Point) From e6934bd20442e46973ca5a63422421a5eac8293f Mon Sep 17 00:00:00 2001 From: AlexB Date: Wed, 6 Dec 2023 10:26:10 -0500 Subject: [PATCH 07/10] Removed a space I suspect is preventing the automated code reviewer from completing --- geometry/triangle.py | 1 - 1 file changed, 1 deletion(-) diff --git a/geometry/triangle.py b/geometry/triangle.py index 2eb2ffa24c58..9b04656c186f 100644 --- a/geometry/triangle.py +++ b/geometry/triangle.py @@ -42,7 +42,6 @@ class Triangle: >>> p2 = Point(1.0,0.0) >>> p3 = Point(0.0,1.0) >>> Triangle(p1, p2, p3) - Triangle(v1=Point(x=-1.0, y=0.0), v2=Point(x=1.0, y=0.0), v3=Point(x=0.0, y=1.0), circum=Point(x=0.0, y=0.0), incen=Point(x=0.0, y=0.0), ortho=Point(x=0.0, y=0.0)) From 736bc66dd0376b81206173ca48b4152bb80a5106 Mon Sep 17 00:00:00 2001 From: AlexB Date: Wed, 6 Dec 2023 10:30:50 -0500 Subject: [PATCH 08/10] Fixed a documentation error --- geometry/triangle.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geometry/triangle.py b/geometry/triangle.py index 9b04656c186f..ec5872231a23 100644 --- a/geometry/triangle.py +++ b/geometry/triangle.py @@ -41,10 +41,10 @@ class Triangle: >>> p1 = Point(-1.0,0.0) >>> p2 = Point(1.0,0.0) >>> p3 = Point(0.0,1.0) - >>> Triangle(p1, p2, p3) + >>> Triangle(p1, p2, p3) # doctest: +NORMALIZE_WHITESPACE Triangle(v1=Point(x=-1.0, y=0.0), v2=Point(x=1.0, y=0.0), v3=Point(x=0.0, y=1.0), - circum=Point(x=0.0, y=0.0), incen=Point(x=0.0, y=0.0), - ortho=Point(x=0.0, y=0.0)) + circum=Point(x=0.0, y=0.0), incen=Point(x=0.0, y=0.0), + ortho=Point(x=0.0, y=0.0)) """ v1: Point = field(default_factory=Point) From ced0a09767b82dfe55123162e1a385119e966ce2 Mon Sep 17 00:00:00 2001 From: cclauss Date: Sun, 13 Sep 2026 05:56:59 +0000 Subject: [PATCH 09/10] updating DIRECTORY.md --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 56ac6b94994c..a6800acdac4a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -425,6 +425,7 @@ * [Climbing Stairs](dynamic_programming/climbing_stairs.py) * [Combination Sum Iv](dynamic_programming/combination_sum_iv.py) * [Edit Distance](dynamic_programming/edit_distance.py) + * [Egg Dropping](dynamic_programming/egg_dropping.py) * [Factorial](dynamic_programming/factorial.py) * [Fast Fibonacci](dynamic_programming/fast_fibonacci.py) * [Fibonacci](dynamic_programming/fibonacci.py) @@ -542,6 +543,7 @@ * Tests * [Test Graham Scan](geometry/tests/test_graham_scan.py) * [Test Jarvis March](geometry/tests/test_jarvis_march.py) + * [Triangle](geometry/triangle.py) ## [Graphics](graphics) * [Bezier Curve](graphics/bezier_curve.py) @@ -591,6 +593,7 @@ * [Graphs Floyd Warshall](graphs/graphs_floyd_warshall.py) * [Greedy Best First](graphs/greedy_best_first.py) * [Greedy Min Vertex Cover](graphs/greedy_min_vertex_cover.py) + * [Hopcroft Karp](graphs/hopcroft_karp.py) * [Johnson](graphs/johnson.py) * [Kahns Algorithm Long](graphs/kahns_algorithm_long.py) * [Kahns Algorithm Topo](graphs/kahns_algorithm_topo.py) From c3746d184949373166ef7db5724e517a30b16249 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 13 Sep 2026 07:59:03 +0200 Subject: [PATCH 10/10] Apply suggestion from @cclauss --- geometry/triangle.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/geometry/triangle.py b/geometry/triangle.py index ec5872231a23..742e9088c760 100644 --- a/geometry/triangle.py +++ b/geometry/triangle.py @@ -66,9 +66,8 @@ def __post_init__(self) -> None: if self.v1 in (self.v2, self.v3): raise TypeError("All 3 arguments should be unique") # Check for linearity - if self.v1.x == self.v2.x: - if self.v3.y == self.v2.y: - raise TypeError("One or more arguments are redundant") + if self.v1.x == self.v2.x and self.v3.y == self.v2.y: + raise TypeError("One or more arguments are redundant") m = (self.v1.y - self.v2.y) / (self.v1.x - self.v2.x) yb = self.v1.y - m * self.v1.x if self.v3.y == m * self.v3.x + yb: