Submission for https://www.hackerrank.com/challenges/lambda-march-compute-the-perimeter-of-a-polygon

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
module Main where
import Control.Monad
type Point = (Integer, Integer)
type Polygon = [Point]
type Side = (Point, Point)
type PolygonSides = [Side]
indexes :: [a] -> [Int]
indexes x =
[0..l - 1] where l = length x
sibling :: [a] -> Int -> (a, a)
sibling l i =
if i == (length l) - 1
then (l !! i, l !! 0)
else (l !! i, l !! (i + 1))
parsePolygon :: String -> Polygon
parsePolygon s =
map parsePoint $ lines s
where
parsePoint :: String -> Point
parsePoint s = (list !! 0, list !! 1) where list = map read $ words s
sideLength :: Side -> Float
sideLength ((x1, y1), (x2, y2)) =
sqrt $ (x1' - x2') ** 2 + (y1' - y2') ** 2
where [x1', y1', x2', y2'] = map fromIntegral [x1, y1, x2, y2]
perimeter :: Polygon -> Float
perimeter polygon =
sum $ map sideLength sides
where
polygonSides :: Polygon -> PolygonSides
polygonSides p = map (sibling polygon) (indexes p)
sides = polygonSides polygon
main :: IO()
main = do
_ <- readLn :: IO Int
contents <- getContents
print $ perimeter $ parsePolygon contents