From 3d1b8e22d8a8e6919ece784701e2445ab98e9166 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Sat, 4 Jul 2020 20:08:07 +0200 Subject: [PATCH 1/2] Added rust implementation of the jarvis march algorithm Added rust implementation of the jarvis march algorithm --- CONTRIBUTORS.md | 1 + .../jarvis_march/code/rust/jarvis_march.rs | 65 +++++++++++++++++++ contents/jarvis_march/jarvis_march.md | 2 + 3 files changed, 68 insertions(+) create mode 100644 contents/jarvis_march/code/rust/jarvis_march.rs diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 17d2e9803..58f087e36 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -51,3 +51,4 @@ This file lists everyone, who contributed to this repo and wanted to show up her - Vincent Zalzal - Jonathan D B Van Schenck - James Goytia +- Jonathan Dönszelmann diff --git a/contents/jarvis_march/code/rust/jarvis_march.rs b/contents/jarvis_march/code/rust/jarvis_march.rs new file mode 100644 index 000000000..28e5ff862 --- /dev/null +++ b/contents/jarvis_march/code/rust/jarvis_march.rs @@ -0,0 +1,65 @@ + +// Define a point to be a tuple of two integers +type Point = (i64, i64); + +// Is the turn counter clockwise? +fn turn_counter_clockwise(p1: Point, p2: Point, p3: Point) -> bool { + (p3.1 - p1.1) * (p2.0 - p1.0) >= (p2.1 - p1.1) * (p3.0 - p1.0) +} + +fn jarvis_march(gift: Vec) -> Option> { + // There can only be a convex hull if there are more than 2 points + if gift.len() < 3 { + return None; + } + + let leftmost_point = gift + // Iterate over all points + .iter() + .cloned() + // Find the point with minimum x + .min_by_key(|i| i.0) + // If there are no points in the gift, there might + // not be a minimum. Unwrap fails (panics) the program + // if there wasn't a minimum, but we know there always + // is because we checked the size of the gift. + .unwrap(); + + let mut hull = vec![leftmost_point]; + + let mut point_on_hull = leftmost_point; + loop { + // Search for the next point on the hull + let mut endpoint = gift[0]; + for i in 1..gift.len() { + if endpoint == point_on_hull || !turn_counter_clockwise(gift[i], hull[hull.len() - 1], endpoint) { + endpoint = gift[i]; + } + } + + point_on_hull = endpoint; + + // Stop whenever we got back to the same point + // as we started with, and we wrapped the gift + // completely. + if hull[0] == endpoint { + break; + } else { + hull.push(point_on_hull); + } + } + + Some(hull) +} + +fn main() { + let test_gift = vec![ + (-5, 2), (5, 7), (-6, -12), (-14, -14), (9, 9), + (-1, -1), (-10, 11), (-6, 15), (-6, -8), (15, -9), + (7, -7), (-2, -9), (6, -5), (0, 14), (2, 8) + ]; + + let hull = jarvis_march(test_gift); + + println!("The points in the hull are: {:?}", hull); +} diff --git a/contents/jarvis_march/jarvis_march.md b/contents/jarvis_march/jarvis_march.md index a5ffca589..0a48dbd85 100644 --- a/contents/jarvis_march/jarvis_march.md +++ b/contents/jarvis_march/jarvis_march.md @@ -48,6 +48,8 @@ Since this algorithm, there have been many other algorithms that have advanced t [import, lang:"go"](code/golang/jarvis.go) {% sample lang="v" %} [import, lang:"v"](code/v/jarvis.v) +{% sample lang="rust" %} +[import, lang:"rust"](code/rust/jarvis_march.rs) {% endmethod %}