69 lines
1.2 KiB
Haskell
69 lines
1.2 KiB
Haskell
import Data.List (intercalate)
|
|
import Data.Function (on)
|
|
|
|
----------------------- RANGE FORMAT ---------------------
|
|
rangeFormat :: [Int] -> String
|
|
rangeFormat = intercalate "," . fmap rangeString . splitBy ((/=) . succ)
|
|
|
|
rangeString xs
|
|
| 2 < length xs = x ++ '-' : last t
|
|
| otherwise = intercalate "," ps
|
|
where
|
|
ps@(x:t) = show <$> xs
|
|
|
|
--------------------- GENERIC FUNCTION -------------------
|
|
-- Split wherever a supplied predicate matches the
|
|
-- relationship between two consecutive items.
|
|
splitBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
|
splitBy _ [] = []
|
|
splitBy _ [x] = [[x]]
|
|
splitBy f xs@(_:t) = uncurry (:) $ foldr go ([], []) (zip xs t)
|
|
where
|
|
go (x, prev) (active, acc)
|
|
| f x prev = ([x], current : acc)
|
|
| otherwise = (x : current, acc)
|
|
where
|
|
current
|
|
| null active = [prev]
|
|
| otherwise = active
|
|
|
|
--------------------------- TEST -------------------------
|
|
main :: IO ()
|
|
main =
|
|
print $
|
|
rangeFormat
|
|
[ 0
|
|
, 1
|
|
, 2
|
|
, 4
|
|
, 6
|
|
, 7
|
|
, 8
|
|
, 11
|
|
, 12
|
|
, 14
|
|
, 15
|
|
, 16
|
|
, 17
|
|
, 18
|
|
, 19
|
|
, 20
|
|
, 21
|
|
, 22
|
|
, 23
|
|
, 24
|
|
, 25
|
|
, 27
|
|
, 28
|
|
, 29
|
|
, 30
|
|
, 31
|
|
, 32
|
|
, 33
|
|
, 35
|
|
, 36
|
|
, 37
|
|
, 38
|
|
, 39
|
|
]
|