Adjacent number algorithm grouper

前端 未结 13 1740
不思量自难忘°
不思量自难忘° 2021-02-15 06:55

By which I mean this:

Given the input set of numbers:

1,2,3,4,5 becomes \"1-5\".

1,2,3,5,7,9,10,11,12,14 becomes \"1-3, 5, 7, 9-12, 14\"

This is

13条回答
  •  天涯浪人
    2021-02-15 07:35

    My first thought, in Python:

    def seq_to_ranges(seq):
        first, last = None, None
        for x in sorted(seq):
            if last != None and last + 1 != x:
                yield (first, last)
                first = x
            if first == None: first = x
            last = x
        if last != None: yield (first, last)
    def seq_to_ranges_str(seq):
        return ", ".join("%d-%d" % (first, last) if first != last else str(first) for (first, last) in seq_to_ranges(seq))
    

    Possibly could be cleaner, but it's still waaay easy.

    Plain translation to Haskell:

    import Data.List
    seq_to_ranges :: (Enum a, Ord a) => [a] -> [(a, a)]
    seq_to_ranges = merge . foldl accum (id, Nothing) . sort where
        accum (k, Nothing) x = (k, Just (x, x))
        accum (k, Just (a, b)) x | succ b == x = (k, Just (a, x))
                                 | otherwise   = (k . ((a, b):), Just (x, x))
        merge (k, m) = k $ maybe [] (:[]) m
    seq_to_ranges_str :: (Enum a, Ord a, Show a) => [a] -> String
    seq_to_ranges_str = drop 2 . concatMap r2s . seq_to_ranges where
        r2s (a, b) | a /= b    = ", " ++ show a ++ "-" ++ show b
                   | otherwise = ", " ++ show a
    

    About the same.

提交回复
热议问题