Difference between revisions of "Haskell Quiz/DayRange/Solution Jethr0"
< Haskell Quiz | DayRange
Jump to navigation
Jump to search
m (using a datatype, added type declarations) |
m (using a modified version of groupBy) |
||
Line 4: | Line 4: | ||
-- > dayRange [1,2,3,6,7] |
-- > dayRange [1,2,3,6,7] |
||
-- "Mon-Wed, Sat, Sun" |
-- "Mon-Wed, Sat, Sun" |
||
+ | module DayRange where |
||
⚫ | |||
+ | import Data.List (intersperse,sort) |
||
+ | -- > dayRange [1,2,3,6,7] |
||
+ | -- "Mon-Wed, Sat, Sun" |
||
⚫ | |||
+ | |||
dayRange :: [Int] -> String |
dayRange :: [Int] -> String |
||
− | dayRange = sepComma . map range . map (map toWeekday) . |
+ | dayRange = sepComma . map range . map (map toWeekday) . groupBy' (\a b -> a+1 == b) . sort |
where sepComma = concat . intersperse ", " |
where sepComma = concat . intersperse ", " |
||
toWeekday x = show $ (toEnum (x-1) :: Weekday) |
toWeekday x = show $ (toEnum (x-1) :: Weekday) |
||
Line 13: | Line 18: | ||
| otherwise = head xs ++ "-" ++ last xs |
| otherwise = head xs ++ "-" ++ last xs |
||
+ | -- groupBy compares any element to the first one of the group |
||
− | -- group list of numbers into directly ascending subgroups |
||
+ | -- groupBy' instead compares an element to the last added group element |
||
− | groupAscend :: [Int] -> [[Int]] |
||
+ | groupBy' :: (a -> a -> Bool) -> [a] -> [[a]] |
||
− | groupAscend (x:xs) = together $ foldl ascend ([],[x]) xs |
||
+ | groupBy' f (x:xs) = gb f xs [[x]] |
||
− | where ascend (done,curr) e = if e == (last curr)+1 then (done, curr++[e]) |
||
+ | where gb f (x:xs) ((a:as):bs) = gb f xs $ if f a x then ((x:a:as):bs) |
||
− | else (done++[curr], [e]) |
||
− | + | else ([x]:(a:as):bs) |
|
+ | gb _ [] as = reverse . map reverse $ as |
||
</haskell> |
</haskell> |
Revision as of 17:41, 10 January 2007
-- > dayRange [1,2,3,6,7]
-- "Mon-Wed, Sat, Sun"
module DayRange where
import Data.List (intersperse,sort)
-- > dayRange [1,2,3,6,7]
-- "Mon-Wed, Sat, Sun"
data Weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Show,Enum)
dayRange :: [Int] -> String
dayRange = sepComma . map range . map (map toWeekday) . groupBy' (\a b -> a+1 == b) . sort
where sepComma = concat . intersperse ", "
toWeekday x = show $ (toEnum (x-1) :: Weekday)
range xs | length xs < 3 = sepComma xs
| otherwise = head xs ++ "-" ++ last xs
-- groupBy compares any element to the first one of the group
-- groupBy' instead compares an element to the last added group element
groupBy' :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy' f (x:xs) = gb f xs [[x]]
where gb f (x:xs) ((a:as):bs) = gb f xs $ if f a x then ((x:a:as):bs)
else ([x]:(a:as):bs)
gb _ [] as = reverse . map reverse $ as