Hello everyone !
I was working on this Kattis problem :
https://open.kattis.com/problems/busnumbers
The main algorithm is about grouping together consecutives integers in a list :
e.g.
if the input is : 180 141 174 143 142 175
the output will be 141-143 174 175 180
: first the list is sorted and then when there are MORE than 2 consecutives numbers you shrink by taking only the first and the last of the consecutive number separated by a “-” … seems simple but I struggled with this and I come up with this cumbersome code, I am sure there are more elegant / efficient way to do this in Haskell …
Thanks
main = interact (writeOutput . solve . sort . tail . readInput)
readInput :: String -> [Int]
readInput input = (\x -> read x :: Int) <$> words input
consecutivesHead :: [Int] -> [Int]
consecutivesHead [x] = [x]
consecutivesHead xs = (filterConseq . zipConseq) xs
zipConseq :: [Int] -> [(Int, Int)]
zipConseq lst = zip lst [(head lst) ..]
filterConseq :: [(Int, Int)] -> [Int]
filterConseq lst = if length tmpRes == 2 then [head tmpRes] else tmpRes
where
tmpRes = fst <$> takeWhile (\x -> fst x == snd x) lst
solve :: [Int] -> [[Int]]
solve [] = []
solve xs = let tmpRes = consecutivesHead xs in tmpRes : solve (dropWhile (\x -> x `elem` tmpRes) xs)
writeOutput :: [[Int]] -> String
writeOutput xss = unwords $ printSol <$> xss
where
printSol x
| length x == 1 = show (head x)
| otherwise = show (head x) <> "-" <> show (last x)
Example usage :
λ> solve [2,3,4,5,8,9,10,12,13,15,16,17,20,23,65]
[[2,3,4,5],[8,9,10],[12],[13],[15,16,17],[20],[23],[65]]
λ>