71 lines
1.2 KiB
Haskell
71 lines
1.2 KiB
Haskell
import Data.Char (toUpper)
|
|
|
|
import Data.Maybe (fromMaybe)
|
|
|
|
import Text.Printf (PrintfType, printf)
|
|
|
|
dirs :: [String]
|
|
dirs =
|
|
[ "N"
|
|
, "NbE"
|
|
, "N-NE"
|
|
, "NEbN"
|
|
, "NE"
|
|
, "NEbE"
|
|
, "E-NE"
|
|
, "EbN"
|
|
, "E"
|
|
, "EbS"
|
|
, "E-SE"
|
|
, "SEbE"
|
|
, "SE"
|
|
, "SEbS"
|
|
, "S-SE"
|
|
, "SbE"
|
|
, "S"
|
|
, "SbW"
|
|
, "S-SW"
|
|
, "SWbS"
|
|
, "SW"
|
|
, "SWbW"
|
|
, "W-SW"
|
|
, "WbS"
|
|
, "W"
|
|
, "WbN"
|
|
, "W-NW"
|
|
, "NWbW"
|
|
, "NW"
|
|
, "NWbN"
|
|
, "N-NW"
|
|
, "NbW"
|
|
]
|
|
|
|
-- Index between 0 and 31 -> the corresponding compass point name.
|
|
pointName :: Int -> String
|
|
pointName = capitalize . concatMap (fromMaybe "?" . fromChar) . (dirs !!)
|
|
where
|
|
fromChar c =
|
|
lookup
|
|
c
|
|
[ ('N', "north")
|
|
, ('S', "south")
|
|
, ('E', "east")
|
|
, ('W', "west")
|
|
, ('b', " by ")
|
|
, ('-', "-")
|
|
]
|
|
capitalize (c:cs) = toUpper c : cs
|
|
|
|
-- Degrees -> compass point index between 0 and 31.
|
|
pointIndex :: Double -> Int
|
|
pointIndex d = (round (d * 1000) + 5625) `mod` 360000 `div` 11250
|
|
|
|
printPointName :: PrintfType t => String -> t
|
|
printPointName d =
|
|
let deg = read d :: Double
|
|
idx = pointIndex deg
|
|
in printf "%2d %-18s %6.2f°\n" (idx + 1) (pointName idx) deg
|
|
|
|
main :: IO ()
|
|
main = mapM_ (printPointName . show) [0 .. 31]
|