Skip to content

Instantly share code, notes, and snippets.

@sleibrock
Created January 5, 2017 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sleibrock/af504917ae489f86d2543dd0ff0a008d to your computer and use it in GitHub Desktop.
Save sleibrock/af504917ae489f86d2543dd0ff0a008d to your computer and use it in GitHub Desktop.
HackerRank find the perimeter of a polygon from a list of points
-- Enter your code here. Read input from STDIN. Print output to STDOUT
import Control.Monad (forM)
hypot :: Floating a => a -> a -> a -> a -> a
hypot lx ly rx ry = sqrt $ (((rx-lx)**2)+((ry-ly)**2))
-- Fold over a list of points, taking the Euclidean distance, and
-- rotate the next point between each call until we reach an empty list
fp :: Floating a => a -> [a] -> [[a]] -> a
fp acc (lx:ly:[]) ((rx:ry:[]):t) = fp (acc + (hypot lx ly rx ry)) [rx,ry] t
fp acc (lx:ly:[]) [] = acc
-- Process input from STDIN and output to STDOUT
main :: IO ()
main = do
n <- getLine -- Number of points changes the forM length
points <- forM [1..(read n :: Int)] (\a -> do
lin <- getLine
return $ map (\x -> read x :: Float) $ words lin)
-- add the head to the tail to cycle all points (ex: f 0 A [B,C,A])
putStrLn $ show $ fp 0.0 (head points) $ (tail points)++[(head points)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment