Add permutations and LazyList.length to Util
This commit is contained in:
parent
c632ab023d
commit
ac93582e96
70
src/Util.md
70
src/Util.md
|
@ -10,6 +10,7 @@ import Data.SortedSet
|
|||
import Data.String
|
||||
import Data.List.Lazy
|
||||
import Data.List1
|
||||
import Data.Vect
|
||||
|
||||
%default total
|
||||
```
|
||||
|
@ -88,6 +89,54 @@ rotations xs = rotations' (length xs) xs []
|
|||
in rotations' k next (next :: acc)
|
||||
```
|
||||
|
||||
### permutations
|
||||
|
||||
Lazily generate all of the permutations of a list
|
||||
|
||||
```idris
|
||||
export
|
||||
permutations : List a -> LazyList (List a)
|
||||
permutations [] = pure []
|
||||
permutations xs = do
|
||||
(head, tail) <- select xs
|
||||
tail <- permutations (assert_smaller xs tail)
|
||||
pure $ head :: tail
|
||||
where
|
||||
consSnd : a -> (a, List a) -> (a, List a)
|
||||
consSnd x (y, xs) = (y, x :: xs)
|
||||
select : List a -> LazyList (a, List a)
|
||||
select [] = []
|
||||
select (x :: xs) = (x, xs) :: map (consSnd x) (select xs)
|
||||
```
|
||||
|
||||
## Vect
|
||||
|
||||
```idris hide
|
||||
namespace Vect
|
||||
```
|
||||
|
||||
### permutations
|
||||
|
||||
Lazily generate all the permutations of a Vect
|
||||
|
||||
```idris
|
||||
export
|
||||
permutations : Vect n a -> LazyList (Vect n a)
|
||||
permutations [] = []
|
||||
permutations [x] = [[x]]
|
||||
permutations (x :: xs) = do
|
||||
(head, tail) <- select (x :: xs)
|
||||
tail <- permutations tail
|
||||
pure $ head :: tail
|
||||
where
|
||||
consSnd : a -> (a, Vect m a) -> (a, Vect (S m) a)
|
||||
consSnd x (y, xs) = (y, x :: xs)
|
||||
select : Vect (S m) a -> LazyList (a, Vect m a)
|
||||
select [y] = [(y, [])]
|
||||
select (y :: (z :: ys)) =
|
||||
(y, z :: ys) :: map (consSnd y) (select (z :: ys))
|
||||
```
|
||||
|
||||
## Vectors
|
||||
|
||||
Define some operations for pairs of numbers, treating them roughly like vectors
|
||||
|
@ -166,6 +215,10 @@ off of the string at a time, checking if the needle is a prefix at each step.
|
|||
|
||||
### Cartesian product
|
||||
|
||||
```idris hide
|
||||
namespace LazyList
|
||||
```
|
||||
|
||||
Lazily take the cartesian product of two foldables
|
||||
|
||||
```idris
|
||||
|
@ -203,10 +256,25 @@ lazyGroup : Eq a => LazyList a -> LazyList (List1 a)
|
|||
lazyGroup [] = []
|
||||
lazyGroup (x :: xs) = lazyGroup' xs x (x ::: [])
|
||||
where
|
||||
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a) -> LazyList (List1 a)
|
||||
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a)
|
||||
-> LazyList (List1 a)
|
||||
lazyGroup' [] current acc = [acc]
|
||||
lazyGroup' (y :: ys) current acc@(head ::: tail) =
|
||||
if y == current
|
||||
then lazyGroup' ys current (head ::: (y :: tail))
|
||||
else acc :: lazyGroup (y :: ys)
|
||||
```
|
||||
|
||||
### length
|
||||
|
||||
Calculate the length of a LazyList
|
||||
|
||||
```idris
|
||||
export
|
||||
length : LazyList a -> Nat
|
||||
length = length' 0
|
||||
where
|
||||
length' : Nat -> LazyList a -> Nat
|
||||
length' k [] = k
|
||||
length' k (x :: xs) = length' (S k) xs
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue