We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Post 45
Hacker Rank 19 - Is Convex?
Published on: 2025-06-29
Tags:
elixir, Side Project, Hacker Rank
You are given the Cartesian coordinates of a set of points in a plane (in no particular order). Each of these points is a corner point of some Polygon, , which is not self-intersecting in nature. Can you determine whether or not is a concave polygon? Sample Input 4 0 0 0 1 1 1 1 0 Sample Output NO Okay so for this one there was a few things that I wanted to do in order to find the right answer. First I need to sort the points based of the centroid of the shape. To do that I needed to first find the centroid of the shape, this is a simple function that will add up all the x and y points and divide by the number of points. Once that is done we need to order the list based off the angel from the centroid of the shape. def sort_list(points) do number_of_points = length(points) [cx, cy] = Enum.reduce(points, [0, 0], fn [x, y], [cx, cy] -> [x + cx, y + cy] end) |> (fn [x, y] -> [x / number_of_points, y / number_of_points] end).() Enum.sort_by(points, fn [x, y] -> :math.atan2(y - cy, x - cx) end) end Once this is done you now have the points in the correct order going around the center of the shape. Next step is to take the cross-product of each set of 3 points on the shape. We do this because the cross product will tell us the the direction of the points from one to the next. def find_orientaion(points) do full_loop = points ++ Enum.take(points, 2) # You need to add in the first 2 points to the end Enum.chunk_every(full_loop, 3, 1, :discard) |> Enum.map(&cross_product/1) end # Positive result -> A is counter-clockwise from B # Negative result -> A is clockwise from B defp cross_product([[x1, y1], [x2, y2], [x3, y3]]) do (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2) end This will give us a list of every cross product of each point. Once you have this done you need to be sure that every cross-product is positive or negative. But keep in mind one thing a 0 for the cross-product means that the 3 points are in a straight line, this will mess with the logic to see if any 2 cross-products are either both positive or both negative. (cross1 * cross2 > 0) So we need to remove the 0's from the list. def is_convex(orientations) do non_zero = Enum.filter(orientations, &(&1 != 0)) # If all are zero (degenerate polygon), treat as convex if non_zero == [], do: "NO", else: convex_loop(non_zero, hd(non_zero)) end defp convex_loop([head | tail], check) do if head * check > 0, do: convex_loop(tail, check), else: "YES" end defp convex_loop([], _), do: "NO" That is it... pretty simple if you know all the needed steps for the question.
