Формула расстояния проста:
distance :: Floating a => (a,a) -> (a,a) -> a
distance (x1,y1) (x2,y2) = sqrt $ (x2 - x1)^2 + (y2 - y1)^2
Обратите внимание на использование сопоставления с образцом для декомпозиции аргументов, а не засорения кода с помощью fst
и snd
.
Соответствующее расстояние от данной точки до всех точек в списке равно
distanceFrom :: Floating a => (a,a) -> [(a,a)] -> [a]
distanceFrom p = map (distance p)
Хотя аргументы, по-видимому, отсутствуют, на языке Haskell это известно как частичное применение . В distanceFrom
у нас их два:
distance p
является функцией одной точки, значение которой равно расстоянию этой точки от p
map (distance p)
является функцией списка точек, значение которого равно соответствующим расстояниям этих точек от p
Попробуйте спроектировать функции Haskell для частичного применения, чтобы упростить объединение небольших функций в более крупные. Как отмечалось в ответе ephemient , вы можете продвинуться на шаг дальше, чтобы получить определение pointfree (без явных аргументов) - более элегантный, продвинутый стиль.
Расстояние до каждой точки в buildings
от всех точек в lPoints
равно
main :: IO ()
main = do
mapM_ (putStrLn . unwords . map (printf "%6.3f")) score
where
score = [ distanceFrom x buildings | x <- lPoints ]
Например, при равенстве lPoints
и buildings
получается
0.000 3.162 5.385 5.099 1.414
3.162 0.000 3.606 2.828 2.828
5.385 3.606 0.000 1.000 4.123
5.099 2.828 1.000 0.000 4.000
1.414 2.828 4.123 4.000 0.000
Но это немного скучно в данном конкретном случае, учитывая всю избыточность. Вместо этого выведите строгий верхний треугольник , используйте
strictUpperTriangle :: [[a]] -> [[a]]
strictUpperTriangle [] = []
strictUpperTriangle xs = go (init xs)
where go (x:xs) = tail x : map tail (go xs)
go [] = []
printSUT :: PrintfArg a => [[a]] -> IO ()
printSUT sut = putStr (unlines $ map pad sut)
where n = length sut
pad xs = let k = n - length xs in
unwords $ take k blanks ++ map (printf "%*.3f" w) xs
blanks = repeat (take w $ repeat ' ')
w = 6 :: Int
main :: IO ()
main = printSUT tri
where
score = [ distanceFrom x buildings | x <- lPoints ]
tri = strictUpperTriangle score
Выход:
3.162 5.385 5.099 1.414
3.606 2.828 2.828
1.000 4.123
4.000