From c6c5d81f1be33d8a009c77702655b3df3fcc0413 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Sat, 15 Aug 2020 01:39:18 +0530 Subject: [PATCH 01/10] Added Jarvis Algorithm to compute convex hull Fixed code formatting Fixed code formatting Fixed code formatting Added Jarvis algorithm to compute convex hull Capitalized class name Added requested changes Added requested changes Added jarvis algorithm Added jarvis algorithm to compute convex hull --- geometry/jarvis_algorithm.cpp | 178 ++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 geometry/jarvis_algorithm.cpp diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp new file mode 100644 index 000000000..84f7de4bc --- /dev/null +++ b/geometry/jarvis_algorithm.cpp @@ -0,0 +1,178 @@ +/** + * @file + * @brief Implementation of [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm. + * + * @details + * Given a set of points in the plane. the convex hull of the set + * is the smallest convex polygon that contains all the points of it. + * + * ### Algorithm + * The idea of Jarvis’s Algorithm is simple, we start from the leftmost point + * (or point with minimum x coordinate value) and we + * keep wrapping points in counterclockwise direction. + * + * The idea is to use orientation() here. Next point is selected as the + * point that beats all other points at counterclockwise orientation, i.e., + * next point is q if for any other point r, + * we have “orientation(p, q, r) = counterclockwise”. + * + * For Example, + * If points = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, + {3, 0}, {0, 0}, {3, 3}}; + * + * then the convex hull is + * (0, 3), (0, 0), (3, 0), (3, 3) + * + * @author [Rishabh Agarwal](https://github.com/rishabh-997) + */ + +#include +#include +#include +#include + +/** + * @namespace geometry + * @brief Geometry algorithms + */ +namespace geometry { + /** + * Structure defining the x and y co-ordinates of the given + * point in space + */ + struct Point { + int x, y; + }; + + /** + * @namespace jarvis + * @brief Functions for [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm + */ + namespace jarvis { + /** + * Class which can be called from main and is globally available + * throughout the code + */ + class Convexhull { + public: + std::vector points; + int size; + + /** + * Constructor of given class + * + * @param pointList list of all points in the space + * @param n number of points in space + */ + Convexhull(std::vector pointList, int n) { + points = std::move(pointList); + size = n; + } + + /** + * Creates convex hull of a set of n points. + * There must be 3 points at least for the convex hull to exist + * + * returns an vector array containing points in space + * which enclose all given points thus forming a hull + */ + std::vector getConvexHull() const { + // Initialize Result + std::vector hull; + + // Find the leftmost point + int leftmost_point = 0; + for (int i = 1; i < size; i++) { + if (points[i].x < points[leftmost_point].x) { + leftmost_point = i; + } + } + // Start from leftmost point, keep moving counterclockwise + // until reach the start point again. This loop runs O(h) + // times where h is number of points in result or output. + int p = leftmost_point, q = 0; + do { + // Add current point to result + hull.push_back(points[p]); + + // Search for a point 'q' such that orientation(p, x, q) + // is counterclockwise for all points 'x'. The idea + // is to keep track of last visited most counter clock- + // wise point in q. If any point 'i' is more counter clock- + // wise than q, then update q. + q = (p + 1) % size; + for (int i = 0; i < size; i++) { + // If i is more counterclockwise than current q, then + // update q + if (orientation(points[p], points[i], points[q]) == 2) { + q = i; + } + } + + // Now q is the most counterclockwise with respect to p + // Set p as q for next iteration, so that q is added to + // result 'hull' + p = q; + + } while (p != leftmost_point); // While we don't come to first point + + return hull; + } + + /** + * + * @param p first point selected + * @param q adjacent point for q + * @param r adjacent point for q + * @returns the geometric orientation for the three points + * 0 -> Linear + * 1 -> Clock Wise + * 2 -> Anti Clock Wise + */ + static int orientation(Point p, Point q, Point r) { + int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + + if (val == 0) { + return 0; + } + return (val > 0) ? 1 : 2; + } + + }; + + } // namespace jarvis +} // namespace geometry + +/** + * Test function + */ +static void test() { + std::vector points = {{0, 3}, + {2, 2}, + {1, 1}, + {2, 1}, + {3, 0}, + {0, 0}, + {3, 3} + }; + int n = points.size(); + geometry::jarvis::Convexhull hull(points, n); + std::vector actualPoint; + actualPoint = hull.getConvexHull(); + + std::vector expectedPoint = {{0, 3}, + {0, 0}, + {3, 0}, + {3, 3}}; + for (int i = 0; i < expectedPoint.size(); i++) { + assert(actualPoint[i].x == expectedPoint[i].x); + assert(actualPoint[i].y == expectedPoint[i].y); + } + std::cout << "Test implementations passed!\n"; +} + +/** Driver Code */ +int main() { + test(); + return 0; +} From e59559af0f97f0f2996a71a13b1872a8c874a9b8 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Sat, 15 Aug 2020 13:05:28 +0530 Subject: [PATCH 02/10] Added jarvis algorithm --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 84f7de4bc..9a1b4ea8d 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -73,7 +73,7 @@ namespace geometry { * Creates convex hull of a set of n points. * There must be 3 points at least for the convex hull to exist * - * returns an vector array containing points in space + * @returns an vector array containing points in space * which enclose all given points thus forming a hull */ std::vector getConvexHull() const { From 686ceb3cfad6192ddfa9d174113d68afcb818ab9 Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:12:37 +0530 Subject: [PATCH 03/10] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 9a1b4ea8d..c0e906886 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -145,6 +145,7 @@ namespace geometry { /** * Test function + * @returns void */ static void test() { std::vector points = {{0, 3}, From ff4792d369ce453ebcb97b1b68ad1c39a4b8301b Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:12:56 +0530 Subject: [PATCH 04/10] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index c0e906886..ff31207a3 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -46,7 +46,7 @@ namespace geometry { /** * @namespace jarvis - * @brief Functions for [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm + * @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm */ namespace jarvis { /** From bfed4c8fba4900a7545576858297476b5268ac81 Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:26:13 +0530 Subject: [PATCH 05/10] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index ff31207a3..85716e2fd 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -1,6 +1,6 @@ /** * @file - * @brief Implementation of [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm. + * @brief Implementation of [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm. * * @details * Given a set of points in the plane. the convex hull of the set From 78ecea32743f539d8a14d0f6e1678e41368960d5 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 16 Aug 2020 19:32:56 +0000 Subject: [PATCH 06/10] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 76fa1154d..60f4717a4 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -82,6 +82,7 @@ * [Dfs With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dfs_with_stack.cpp) * [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dijkstra.cpp) * [Hamiltons Cycle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/hamiltons_cycle.cpp) + * [Is Graph Bipartite](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/is_graph_bipartite.cpp) * [Kosaraju](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kosaraju.cpp) * [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kruskal.cpp) * [Lowest Common Ancestor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/lowest_common_ancestor.cpp) From d21f56e8363c10e956bf015bd33e78a408861217 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Mon, 17 Aug 2020 02:36:30 +0530 Subject: [PATCH 07/10] Added Jarvi algo to find convex hull --- geometry/jarvis_algorithm.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 85716e2fd..d471a52a4 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -36,19 +36,19 @@ * @brief Geometry algorithms */ namespace geometry { - /** - * Structure defining the x and y co-ordinates of the given - * point in space - */ - struct Point { - int x, y; - }; - /** * @namespace jarvis * @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm */ namespace jarvis { + /** + * Structure defining the x and y co-ordinates of the given + * point in space + */ + struct Point { + int x, y; + }; + /** * Class which can be called from main and is globally available * throughout the code @@ -148,7 +148,7 @@ namespace geometry { * @returns void */ static void test() { - std::vector points = {{0, 3}, + std::vector points = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, @@ -158,10 +158,10 @@ static void test() { }; int n = points.size(); geometry::jarvis::Convexhull hull(points, n); - std::vector actualPoint; + std::vector actualPoint; actualPoint = hull.getConvexHull(); - std::vector expectedPoint = {{0, 3}, + std::vector expectedPoint = {{0, 3}, {0, 0}, {3, 0}, {3, 3}}; From bf610fb91dad7f62aeee7c647ddf43dcbc0fe92e Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Mon, 17 Aug 2020 02:46:38 +0530 Subject: [PATCH 08/10] Added Jarvi algo to find convex hull --- geometry/jarvis_algorithm.cpp | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index d471a52a4..ae5b1b5a6 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -26,7 +26,6 @@ * @author [Rishabh Agarwal](https://github.com/rishabh-997) */ -#include #include #include #include @@ -54,19 +53,19 @@ namespace geometry { * throughout the code */ class Convexhull { - public: std::vector points; int size; + public: /** * Constructor of given class * * @param pointList list of all points in the space * @param n number of points in space */ - Convexhull(std::vector pointList, int n) { - points = std::move(pointList); - size = n; + explicit Convexhull(const std::vector &pointList) { + points = pointList; + size = points.size(); } /** @@ -120,16 +119,18 @@ namespace geometry { } /** - * + * This function returns the geometric orientation for the three points + * in a space, ie, whether they are linear ir clockwise or + * anti-clockwise * @param p first point selected * @param q adjacent point for q * @param r adjacent point for q - * @returns the geometric orientation for the three points - * 0 -> Linear - * 1 -> Clock Wise - * 2 -> Anti Clock Wise + * + * @returns 0 -> Linear + * @returns 1 -> Clock Wise + * @returns 2 -> Anti Clock Wise */ - static int orientation(Point p, Point q, Point r) { + static int orientation(const Point &p, const Point &q, const Point &r) { int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); if (val == 0) { @@ -149,22 +150,21 @@ namespace geometry { */ static void test() { std::vector points = {{0, 3}, - {2, 2}, - {1, 1}, - {2, 1}, - {3, 0}, - {0, 0}, - {3, 3} + {2, 2}, + {1, 1}, + {2, 1}, + {3, 0}, + {0, 0}, + {3, 3} }; - int n = points.size(); - geometry::jarvis::Convexhull hull(points, n); + geometry::jarvis::Convexhull hull(points); std::vector actualPoint; actualPoint = hull.getConvexHull(); std::vector expectedPoint = {{0, 3}, - {0, 0}, - {3, 0}, - {3, 3}}; + {0, 0}, + {3, 0}, + {3, 3}}; for (int i = 0; i < expectedPoint.size(); i++) { assert(actualPoint[i].x == expectedPoint[i].x); assert(actualPoint[i].y == expectedPoint[i].y); From 91ce393c4560302d2d38fba380e3edb185659a3b Mon Sep 17 00:00:00 2001 From: Filip Hlasek Date: Sun, 16 Aug 2020 21:23:29 -0700 Subject: [PATCH 09/10] fix: linter for kruskal (#1036) * fix: linter for kruskal * using instead of typedef. --- graph/kruskal.cpp | 113 +++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 82 deletions(-) diff --git a/graph/kruskal.cpp b/graph/kruskal.cpp index b7b830668..e179131a1 100644 --- a/graph/kruskal.cpp +++ b/graph/kruskal.cpp @@ -1,73 +1,21 @@ #include +#include +#include +#include //#include // using namespace boost::multiprecision; const int mx = 1e6 + 5; -const long int inf = 2e9; -typedef long long ll; -#define rep(i, n) for (i = 0; i < n; i++) -#define repp(i, a, b) for (i = a; i <= b; i++) -#define pii pair -#define vpii vector -#define vi vector -#define vll vector -#define r(x) scanf("%d", &x) -#define rs(s) scanf("%s", s) -#define gc getchar_unlocked -#define pc putchar_unlocked -#define mp make_pair -#define pb push_back -#define lb lower_bound -#define ub upper_bound -#define endl "\n" -#define fast \ - ios_base::sync_with_stdio(false); \ - cin.tie(NULL); \ - cout.tie(NULL); -using namespace std; -void in(int &x) { - register int c = gc(); - x = 0; - int neg = 0; - for (; ((c < 48 || c > 57) && c != '-'); c = gc()) - ; - if (c == '-') { - neg = 1; - c = gc(); - } - for (; c > 47 && c < 58; c = gc()) { - x = (x << 1) + (x << 3) + c - 48; - } - if (neg) - x = -x; -} -void out(int n) { - int N = n, rev, count = 0; - rev = N; - if (N == 0) { - pc('0'); - return; - } - while ((rev % 10) == 0) { - count++; - rev /= 10; - } - rev = 0; - while (N != 0) { - rev = (rev << 3) + (rev << 1) + N % 10; - N /= 10; - } - while (rev != 0) { - pc(rev % 10 + '0'); - rev /= 10; - } - while (count--) pc('0'); -} -ll parent[mx], arr[mx], node, edge; -vector>> v; +using ll = int64_t; + +std::array parent; +ll node, edge; +std::vector>> edges; void initial() { - int i; - rep(i, node + edge) parent[i] = i; + for (int i = 0; i < node + edge; ++i) { + parent[i] = i; + } } + int root(int i) { while (parent[i] != i) { parent[i] = parent[parent[i]]; @@ -75,41 +23,42 @@ int root(int i) { } return i; } + void join(int x, int y) { int root_x = root(x); // Disjoint set union by rank int root_y = root(y); parent[root_x] = root_y; } + ll kruskal() { - ll mincost = 0, i, x, y; - rep(i, edge) { - x = v[i].second.first; - y = v[i].second.second; + ll mincost = 0; + for (int i = 0; i < edge; ++i) { + ll x = edges[i].second.first; + ll y = edges[i].second.second; if (root(x) != root(y)) { - mincost += v[i].first; + mincost += edges[i].first; join(x, y); } } return mincost; } + int main() { - fast; - while (1) { - int i, j, from, to, cost, totalcost = 0; - cin >> node >> edge; // Enter the nodes and edges - if (node == 0 && edge == 0) + while (true) { + int from = 0, to = 0, cost = 0, totalcost = 0; + std::cin >> node >> edge; // Enter the nodes and edges + if (node == 0 && edge == 0) { break; // Enter 0 0 to break out + } initial(); // Initialise the parent array - rep(i, edge) { - cin >> from >> to >> cost; - v.pb(mp(cost, mp(from, to))); + for (int i = 0; i < edge; ++i) { + std::cin >> from >> to >> cost; + edges.emplace_back(make_pair(cost, std::make_pair(from, to))); totalcost += cost; } - sort(v.begin(), v.end()); - // rep(i,v.size()) - // cout< Date: Sun, 16 Aug 2020 21:43:33 -0700 Subject: [PATCH 10/10] fix: linter for kosaraju (#1035) * fix: linter for kosaraju * update doxygen parameters --- graph/kosaraju.cpp | 87 +++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/graph/kosaraju.cpp b/graph/kosaraju.cpp index 00c9d7ca0..5949c0bb8 100644 --- a/graph/kosaraju.cpp +++ b/graph/kosaraju.cpp @@ -4,77 +4,84 @@ #include #include +#include -using namespace std; /** * Iterative function/method to print graph: - * @param a[] : array of vectors (2D) - * @param V : vertices + * @param a adjacency list representation of the graph + * @param V number of vertices * @return void **/ -void print(vector a[], int V) { +void print(const std::vector< std::vector > &a, int V) { for (int i = 0; i < V; i++) { - if (!a[i].empty()) - cout << "i=" << i << "-->"; - for (int j = 0; j < a[i].size(); j++) cout << a[i][j] << " "; - if (!a[i].empty()) - cout << endl; + if (!a[i].empty()) { + std::cout << "i=" << i << "-->"; + } + for (int j : a[i]) { + std::cout << j << " "; + } + if (!a[i].empty()) { + std::cout << std::endl; + } } } /** * //Recursive function/method to push vertices into stack passed as parameter: - * @param v : vertices - * @param &st : stack passed by reference - * @param vis[] : array to keep track of visited nodes (boolean type) - * @param adj[] : array of vectors to represent graph + * @param v vertices + * @param st stack passed by reference + * @param vis array to keep track of visited nodes (boolean type) + * @param adj adjacency list representation of the graph * @return void **/ -void push_vertex(int v, stack &st, bool vis[], vector adj[]) { - vis[v] = true; +void push_vertex(int v, std::stack *st, std::vector *vis, const std::vector< std::vector > &adj) { + (*vis)[v] = true; for (auto i = adj[v].begin(); i != adj[v].end(); i++) { - if (vis[*i] == false) + if ((*vis)[*i] == false) { push_vertex(*i, st, vis, adj); + } } - st.push(v); + st->push(v); } /** * //Recursive function/method to implement depth first traversal(dfs): - * @param v : vertices - * @param vis[] : array to keep track of visited nodes (boolean type) - * @param grev[] : graph with reversed edges + * @param v vertices + * @param vis array to keep track of visited nodes (boolean type) + * @param grev graph with reversed edges * @return void **/ -void dfs(int v, bool vis[], vector grev[]) { - vis[v] = true; +void dfs(int v, std::vector *vis, const std::vector< std::vector > &grev) { + (*vis)[v] = true; // cout<0)) i.e. it returns the count of (number of) strongly connected components (SCCs) in the graph. (variable 'count_scc' within function) **/ -int kosaraju(int V, vector adj[]) { - bool vis[V] = {}; - stack st; +int kosaraju(int V, const std::vector< std::vector > &adj) { + std::vector vis(V, false); + std::stack st; for (int v = 0; v < V; v++) { - if (vis[v] == false) - push_vertex(v, st, vis, adj); + if (vis[v] == false) { + push_vertex(v, &st, &vis, adj); + } } // making new graph (grev) with reverse edges as in adj[]: - vector grev[V]; + std::vector< std::vector > grev(V); for (int i = 0; i < V + 1; i++) { for (auto j = adj[i].begin(); j != adj[i].end(); j++) { grev[*j].push_back(i); @@ -89,7 +96,7 @@ int kosaraju(int V, vector adj[]) { int t = st.top(); st.pop(); if (vis[t] == false) { - dfs(t, vis, grev); + dfs(t, &vis, grev); count_scc++; } } @@ -101,21 +108,21 @@ int kosaraju(int V, vector adj[]) { // All critical/corner cases have been taken care of. // Input your required values: (not hardcoded) int main() { - int t; - cin >> t; + int t = 0; + std::cin >> t; while (t--) { - int a, b; // a->number of nodes, b->directed edges. - cin >> a >> b; - int m, n; - vector adj[a + 1]; + int a = 0, b = 0; // a->number of nodes, b->directed edges. + std::cin >> a >> b; + int m = 0, n = 0; + std::vector< std::vector > adj(a + 1); for (int i = 0; i < b; i++) // take total b inputs of 2 vertices each // required to form an edge. { - cin >> m >> n; // take input m,n denoting edge from m->n. + std::cin >> m >> n; // take input m,n denoting edge from m->n. adj[m].push_back(n); } // pass number of nodes and adjacency array as parameters to function: - cout << kosaraju(a, adj) << endl; + std::cout << kosaraju(a, adj) << std::endl; } return 0; }