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

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -