Add permutations and LazyList.length to Util
This commit is contained in:
parent
c632ab023d
commit
ac93582e96
154
src/Util.md
154
src/Util.md
|
@ -10,6 +10,7 @@ import Data.SortedSet
|
||||||
import Data.String
|
import Data.String
|
||||||
import Data.List.Lazy
|
import Data.List.Lazy
|
||||||
import Data.List1
|
import Data.List1
|
||||||
|
import Data.Vect
|
||||||
|
|
||||||
%default total
|
%default total
|
||||||
```
|
```
|
||||||
|
@ -56,13 +57,13 @@ namespace List
|
||||||
Returns `True` if the list contains the given value
|
Returns `True` if the list contains the given value
|
||||||
|
|
||||||
```idris
|
```idris
|
||||||
export
|
export
|
||||||
contains : Eq a => a -> List a -> Bool
|
contains : Eq a => a -> List a -> Bool
|
||||||
contains x [] = False
|
contains x [] = False
|
||||||
contains x (y :: xs) =
|
contains x (y :: xs) =
|
||||||
if x == y
|
if x == y
|
||||||
then True
|
then True
|
||||||
else contains x xs
|
else contains x xs
|
||||||
```
|
```
|
||||||
|
|
||||||
### rotations
|
### rotations
|
||||||
|
@ -76,16 +77,64 @@ rotations [1, 2, 3] == [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
|
||||||
```
|
```
|
||||||
|
|
||||||
```idris
|
```idris
|
||||||
export
|
export
|
||||||
rotations : List a -> List (List a)
|
rotations : List a -> List (List a)
|
||||||
rotations xs = rotations' (length xs) xs []
|
rotations xs = rotations' (length xs) xs []
|
||||||
where
|
where
|
||||||
rotations' : Nat -> List a -> (acc : List (List a)) -> List (List a)
|
rotations' : Nat -> List a -> (acc : List (List a)) -> List (List a)
|
||||||
rotations' 0 xs acc = acc
|
rotations' 0 xs acc = acc
|
||||||
rotations' (S k) [] acc = acc
|
rotations' (S k) [] acc = acc
|
||||||
rotations' (S k) (x :: xs) acc =
|
rotations' (S k) (x :: xs) acc =
|
||||||
let next = xs ++ [x]
|
let next = xs ++ [x]
|
||||||
in rotations' k next (next :: acc)
|
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
|
## Vectors
|
||||||
|
@ -166,20 +215,24 @@ off of the string at a time, checking if the needle is a prefix at each step.
|
||||||
|
|
||||||
### Cartesian product
|
### Cartesian product
|
||||||
|
|
||||||
|
```idris hide
|
||||||
|
namespace LazyList
|
||||||
|
```
|
||||||
|
|
||||||
Lazily take the cartesian product of two foldables
|
Lazily take the cartesian product of two foldables
|
||||||
|
|
||||||
```idris
|
```idris
|
||||||
export
|
export
|
||||||
cartProd : Foldable a => Foldable b => a e -> b f -> LazyList (e, f)
|
cartProd : Foldable a => Foldable b => a e -> b f -> LazyList (e, f)
|
||||||
cartProd x y =
|
cartProd x y =
|
||||||
let y = foldToLazy y
|
let y = foldToLazy y
|
||||||
in foldr (\e, acc => combine e y acc) [] x
|
in foldr (\e, acc => combine e y acc) [] x
|
||||||
where
|
where
|
||||||
foldToLazy : Foldable a' => a' e' -> LazyList e'
|
foldToLazy : Foldable a' => a' e' -> LazyList e'
|
||||||
foldToLazy x = foldr (\e, acc => e :: acc) [] x
|
foldToLazy x = foldr (\e, acc => e :: acc) [] x
|
||||||
combine : e -> LazyList f -> LazyList (e, f) -> LazyList (e, f)
|
combine : e -> LazyList f -> LazyList (e, f) -> LazyList (e, f)
|
||||||
combine x [] rest = rest
|
combine x [] rest = rest
|
||||||
combine x (y :: ys) rest = (x, y) :: combine x ys rest
|
combine x (y :: ys) rest = (x, y) :: combine x ys rest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Concat
|
### Concat
|
||||||
|
@ -187,10 +240,10 @@ cartProd x y =
|
||||||
Lazily concatenate a LazyList of LazyLists
|
Lazily concatenate a LazyList of LazyLists
|
||||||
|
|
||||||
```idris
|
```idris
|
||||||
export
|
export
|
||||||
lazyConcat : LazyList (LazyList a) -> LazyList a
|
lazyConcat : LazyList (LazyList a) -> LazyList a
|
||||||
lazyConcat [] = []
|
lazyConcat [] = []
|
||||||
lazyConcat (x :: xs) = x ++ lazyConcat xs
|
lazyConcat (x :: xs) = x ++ lazyConcat xs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Group
|
### Group
|
||||||
|
@ -198,15 +251,30 @@ lazyConcat (x :: xs) = x ++ lazyConcat xs
|
||||||
Lazily group a LazyList
|
Lazily group a LazyList
|
||||||
|
|
||||||
```idris
|
```idris
|
||||||
export
|
export
|
||||||
lazyGroup : Eq a => LazyList a -> LazyList (List1 a)
|
lazyGroup : Eq a => LazyList a -> LazyList (List1 a)
|
||||||
lazyGroup [] = []
|
lazyGroup [] = []
|
||||||
lazyGroup (x :: xs) = lazyGroup' xs x (x ::: [])
|
lazyGroup (x :: xs) = lazyGroup' xs x (x ::: [])
|
||||||
where
|
where
|
||||||
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a) -> LazyList (List1 a)
|
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a)
|
||||||
lazyGroup' [] current acc = [acc]
|
-> LazyList (List1 a)
|
||||||
lazyGroup' (y :: ys) current acc@(head ::: tail) =
|
lazyGroup' [] current acc = [acc]
|
||||||
if y == current
|
lazyGroup' (y :: ys) current acc@(head ::: tail) =
|
||||||
then lazyGroup' ys current (head ::: (y :: tail))
|
if y == current
|
||||||
else acc :: lazyGroup (y :: ys)
|
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