Haskell: Higher Order function to use to group an increasing decreasing list -
given list [1,2,31,23,22,1,43]
use higher order function group elements [[1,2,31], [23,22,1], [43]]
. increasing / decreasing list, elements elements in increasing order , in decreasing order.
groupincdec :: ord => [a] -> [[a]]
each element in output list [[a]]
should either increasing or decreasing, in example above, first element [1,2,31]
increasing, second [23,22,1]
decreasing , because there single element left , previous state decreasing, [43]
can classified increasing.
could not figure out if/how use groupby
. hints appreciated.
thanks.
[edit: added more description, clarify question further.]
here's approach. moment, let's assume list has no adjacent equal elements, example. if list lst
compared own tail, element-by-element:
> let lst = [1,2,31,23,22,1,43] > let dir = zipwith compare lst (tail lst) > dir [lt,lt,gt,gt,gt,lt]
then dir
represents whether adjacent elements increasing or decreasing. if repeat head of list:
> let dir' = head dir : dir > dir' [lt,lt,lt,gt,gt,gt,lt]
then dir'
corresponds how list [1,2,31,23,22,1,43]
should grouped. zipping dir'
lst
, grouping dir'
elements, get:
> import data.function -- `on` > let groups = groupby ((==) `on` fst) (zip dir' lst) > groups [[(lt,1),(lt,2),(lt,31)],[(gt,23),(gt,22),(gt,1)],[(lt,43)]]
which can filter to:
> map (map snd) groups [[1,2,31],[23,22,1],[43]]
so, putting together, higher-order solution:
groupincdec' :: ord => [a] -> [[a]] groupincdec' lst = let dir = zipwith compare lst (tail lst) in map (map snd) $ groupby ((==) `on` fst) $ zip (head dir : dir) lst
this doesn't work on lists adjacent duplicate elements, can take such list:
lst' = [1,2,31,31,23,22,22,1,43]
and group it:
group lst' = [[1],[2],[31,31],[23],[22,22],[1],[43]]
and apply above algorithm before "ungrouping" again final result. looks this:
groupincdec :: ord => [a] -> [[a]] groupincdec xs = let ys = group xs dir = zipwith (comparing head) ys (tail ys) in map (concatmap snd) $ groupby ((==) `on` fst) $ zip (head dir : dir) ys
which works so:
> groupincdec [1,2,31,23,22,1,43] [[1,2,31],[23,22,1],[43]] > groupincdec [1,2,31,31,23,22,22,1,43] [[1,2,31,31],[23,22,22,1],[43]]
Comments
Post a Comment