module Data.Util (
    V.Vector,
    betw, filter3, inject, lowercase, nextn, next5, replace,
    splitat, vnew, (><), (§), (§=), (§:)
) where

import Data.Char (toLower)
import qualified Data.Vector as V
import Data.Vector (Vector)

betw :: Int -> Int -> Int -> Bool
betw :: Int -> Int -> Int -> Bool
betw Int
s Int
e Int
n = Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
e

filter3 :: (Num n, Eq n, Eq a) => (a -> n -> [a] -> Bool) -> [a] -> [a]
filter3 :: forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a]
filter3 a -> n -> [a] -> Bool
fun [a]
ys = (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
fun [a]
ys [a]
ys [] n
0
 where
    map3 :: (Num n, Eq n, Eq a) =>
        (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
    map3 :: forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
_ [a]
_ [] [a]
ta n
_ = [a] -> [a]
forall a. [a] -> [a]
reverse [a]
ta
    map3 a -> n -> [a] -> Bool
f [a]
xs [a
a] ![a]
ta !n
n = if a -> n -> [a] -> Bool
f a
a n
n [a]
xs then
        (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
f [a]
xs [] (a
aa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ta) (n
n n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)
        else (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
f [a]
xs [] [a]
ta (n
n n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)
    map3 a -> n -> [a] -> Bool
f [a]
xs (a
a:[a]
as) ![a]
ta !n
n = if a -> n -> [a] -> Bool
f a
a n
n [a]
xs then
        (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
f [a]
xs [a]
as (a
aa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ta) (n
n n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)
        else (a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
forall n a.
(Num n, Eq n, Eq a) =>
(a -> n -> [a] -> Bool) -> [a] -> [a] -> [a] -> n -> [a]
map3 a -> n -> [a] -> Bool
f [a]
xs [a]
as [a]
ta (n
n n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

inject :: Char -> Int -> String -> String
inject :: Char -> Int -> String -> String
inject Char
c Int
p String
xs = let
    (String
left,String
right)    = Int -> String -> (String, String)
splitat Int
p String
xs
    ret :: String
ret             = String
left String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
right)
 in
    String
ret

lowercase :: String -> String
lowercase :: String -> String
lowercase = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toLower

nextn :: Int -> Int -> Int
nextn :: Int -> Int -> Int
nextn Int
n Int
x
    | Int
x Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int
x
nextn Int
n Int
x = Int -> Int -> Int
nextn Int
n (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

next5 :: Int -> Int
next5 :: Int -> Int
next5 = Int -> Int -> Int
nextn Int
5

replace :: Char -> Char -> String -> String
replace :: Char -> Char -> String -> String
replace Char
from Char
to String
xs = [if Char
xChar -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
from then Char
to else Char
x | Char
x <- String
xs]

splitat :: Int -> String -> (String,String)
splitat :: Int -> String -> (String, String)
splitat Int
p String
xs = let
    len :: Int
len     = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xs
    nright :: Int
nright  = Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p
    left :: String
left    = Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
p String
xs
    right :: String
right   = (String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
nright) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse) String
xs
    ret :: (String, String)
ret     = (String
left,String
right)
 in
    (String, String)
ret

vnew :: Int -> a -> Vector a
vnew :: forall a. Int -> a -> Vector a
vnew = Int -> a -> Vector a
forall a. Int -> a -> Vector a
V.replicate

vaccess :: Vector a -> Int -> a
vaccess :: forall a. Vector a -> Int -> a
vaccess Vector a
v Int
n
 | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len = Vector a -> Int -> a
forall a. Vector a -> Int -> a
(V.!) Vector a
v Int
n
 | Bool
otherwise = String -> a
forall a. HasCallStack => String -> a
error String
"Vector out of bounds"
 where
    len :: Int
len = Vector a -> Int
forall a. Vector a -> Int
V.length Vector a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1

vcons :: a -> Vector a -> Vector a
vcons :: forall a. a -> Vector a -> Vector a
vcons a
a Vector a
v
 | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 = let
    olda :: a
olda = Vector a
v Vector a -> Int -> a
forall a. Vector a -> Int -> a
§ Int
0
    v' :: Vector a
v' = (Int -> a -> Bool) -> Vector a -> Vector a
forall a. (Int -> a -> Bool) -> Vector a -> Vector a
V.ifilter Int -> a -> Bool
forall a. Int -> a -> Bool
f Vector a
v
    f :: Int -> a -> Bool
    f :: forall a. Int -> a -> Bool
f Int
i a
_ = Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
    ret :: Vector a
ret = a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
V.cons a
olda (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
V.cons a
a Vector a
v'
 in
    Vector a
ret
 where
    n :: Int
n = Vector a -> Int
forall a. Vector a -> Int
V.length Vector a
v
vcons a
a Vector a
v = a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
V.cons a
a Vector a
v

vset :: Vector a -> Int -> a -> Vector a
vset :: forall a. Vector a -> Int -> a -> Vector a
vset Vector a
v Int
n a
a
 | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len = Vector a -> Vector Int -> Vector a -> Vector a
forall a. Vector a -> Vector Int -> Vector a -> Vector a
V.unsafeUpdate_ Vector a
v (Int -> Vector Int
forall a. a -> Vector a
V.singleton Int
n) (a -> Vector a
forall a. a -> Vector a
V.singleton a
a)
 | Bool
otherwise = String -> Vector a
forall a. HasCallStack => String -> a
error String
"Vector out of bounds"
 where
    len :: Int
len = Vector a -> Int
forall a. Vector a -> Int
V.length Vector a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1

infixl 4 §
(§) :: Vector a -> Int -> a
§ :: forall a. Vector a -> Int -> a
(§) = Vector a -> Int -> a
forall a. Vector a -> Int -> a
vaccess

infixl 4 §=
(§=) :: (Vector a,Int) -> a -> Vector a
§= :: forall a. (Vector a, Int) -> a -> Vector a
(§=) (Vector a
v,Int
n) = Vector a -> Int -> a -> Vector a
forall a. Vector a -> Int -> a -> Vector a
vset Vector a
v Int
n

infixl 4 §:
(§:) :: a -> Vector a -> Vector a
§: :: forall a. a -> Vector a -> Vector a
(§:) = a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
vcons

infixl 4 ><
(><) :: a -> [a] -> [a]
>< :: forall a. a -> [a] -> [a]
(><) a
x = [a] -> [a]
forall a. [a] -> [a]
Prelude.reverse ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:) a
x ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
Prelude.reverse