Skip to content

Commit

Permalink
Make groupsOf and greedyGroupsOf fn families tail-recursive (#157)
Browse files Browse the repository at this point in the history
* Make groupsOf and greedyGroupsOf fn families tail-recursive

* Refactor (thanks @jfmengels)

* Optimize, don't precalculate if we don't need to
  • Loading branch information
Janiczek committed Jan 10, 2022
1 parent 5cb025f commit 4769635
Showing 1 changed file with 39 additions and 30 deletions.
69 changes: 39 additions & 30 deletions src/List/Extra.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1949,25 +1949,33 @@ skipped and not appear in any groups.
-}
groupsOfWithStep : Int -> Int -> List a -> List (List a)
groupsOfWithStep size step xs =
let
thisGroup =
List.take size xs

xs_ =
List.drop step xs
groupsOfWithStep size step list =
if size <= 0 || step <= 0 then
[]

okayArgs =
size > 0 && step > 0
else
let
go : List a -> List (List a) -> List (List a)
go xs acc =
if List.isEmpty xs then
List.reverse acc

okayLength =
size == List.length thisGroup
in
if okayArgs && okayLength then
thisGroup :: groupsOfWithStep size step xs_
else
let
thisGroup =
List.take size xs
in
if size == List.length thisGroup then
let
rest =
List.drop step xs
in
go rest (thisGroup :: acc)

else
[]
else
List.reverse acc
in
go list []


{-| `groupsOfVarying ns` takes `n` elements from a list for each `n` in `ns`, splitting the list into variably sized segments
Expand Down Expand Up @@ -2035,22 +2043,23 @@ elements will be skipped and not appear in any groups.
-}
greedyGroupsOfWithStep : Int -> Int -> List a -> List (List a)
greedyGroupsOfWithStep size step xs =
let
xs_ =
List.drop step xs

okayArgs =
size > 0 && step > 0

okayXs =
List.length xs > 0
in
if okayArgs && okayXs then
List.take size xs :: greedyGroupsOfWithStep size step xs_
greedyGroupsOfWithStep size step list =
if size <= 0 || step <= 0 then
[]

else
[]
let
go : List a -> List (List a) -> List (List a)
go xs acc =
if List.isEmpty xs then
List.reverse acc

else
go
(List.drop step xs)
(List.take size xs :: acc)
in
go list []


{-| Group equal elements together. This is different from `group` as each sublist
Expand Down

0 comments on commit 4769635

Please sign in to comment.