challenge データの整列

(x, y) の座標情報を以下の2種類の方法で整列する機能を実現してください。

  • (x, y) の辞書順(まず x で昇順に整列して、x が同じデータに対して y で昇順に整列する)
  • (0, 0) からの距離の昇順

データの表現方法はタプルなり構造体/オブジェクトなり各自で適当に選んで下さい。

Posted feedbacks - Haskell

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import Data.List

lexicalOrder (x1, y1) (x2, y2)
  | x1 < x2   = LT
  | x1 > x2   = GT
  | y1 < y2   = LT
  | y1 > y2   = GT
  | otherwise = EQ

lengthOrder (x1, y1) (x2, y2) = 
  let length x y = sqrt $ x**2 + y**2 in
    compare (length x1 y1) (length x2 y2)

sample = [(1,1), (3,3), (0,0), (0,3), (4,0)]

main = do
  print $ sortBy lexicalOrder sample
  print $ sortBy lengthOrder  sample

-- [(0.0,0.0),(0.0,3.0),(1.0,1.0),(3.0,3.0),(4.0,0.0)]
-- [(0.0,0.0),(1.0,1.0),(0.0,3.0),(4.0,0.0),(3.0,3.0)]

匿名さんのとほとんど同じですが、微妙な違いとして:
1.辞書順は実は言語サポートがある。
2.distをData.Function.on :: (b -> b -> c) -> (a -> b) -> a -> a -> cを使って適用している。

ところ*だけ*違います。何かのお役に立てば...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
module Main
    where

import Data.List
import Data.Function

byDist :: (Int, Int) -> (Int, Int) -> Ordering
byDist x y = on compare dist x y
    where
        dist (x, y) = x * x + y * y

sortByDict as = sort as
sortByDist as = sortBy byDist as

main = do
    putStrLn $ show lstOrig
    putStrLn "Sort by distance"
    putStrLn.show $ sortByDist lstOrig
    putStrLn "Sort by dictionary order"
    putStrLn.show $ sortByDict lstOrig
    where
        lstOrig = [(1, 2), (2, 1), (4, 30), (9, 0), (-1, -10)]

括弧多めで。

1
2
3
4
5
6
import Data.List

sample = [(1, 1), (3, 3), (0, 0), (0, 3), (4, 0)]
  
main = do (print . sort) sample
          (print . sortBy (\(a, b) (c, d) -> compare (a**2+b**2) (c**2+d**2))) sample


	
1
2
3
import List

sortByMagnitude ps = map snd $ sort $ map (\z@(x,y) -> (x*x+y*y, z)) ps

複素数のライブラリを利用する

sort3 はおまけで、(0,0)からの距離が等しいときはx軸との偏角(-π<θ≦π)で昇順でソート

1
2
3
4
5
6
7
8
9
import Control.Arrow
import Data.Complex
import Data.Function
import Data.List

sort1,sort2,sort3 :: RealFloat a => [(a,a)] -> [(a,a)]
sort1 = sort
sort2 = sortBy (compare `on` magnitude . uncurry (:+))
sort3 = sortBy (compare `on` (magnitude &&& phase) . uncurry (:+))

Index

Feed

Other

Link

Pathtraq

loading...