{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE NoImplicitPrelude #-}

{- |
Module      :  Aftovolio.PermutationsArrMini1
Copyright   :  (c) OleksandrZhabenko 2022-2024
License     :  MIT
Stability   :  Experimental
Maintainer  :  oleksandr.zhabenko@yahoo.com

Special permutations functions for the phonetic-languages and phladiprelio series of packages. This
module uses no vectors, but instead uses arrays.
-}
module Aftovolio.PermutationsArrMini1 (
    genElementaryPermutations1,
    pairsSwapP1,
    genElementaryPermutationsArrN1,
    genElementaryPermutationsArr1,
    genElementaryPermutationsLN1,
    genElementaryPermutationsL1,
    genElementaryPermutationsArrLN1,
    genElementaryPermutationsArrL1,
) where

import GHC.Arr
import GHC.Base
import GHC.Enum
import GHC.List
import GHC.Num (Num, abs, (+), (-))

genElementaryPermutations1 :: (Ord a, Enum a, Num a) => Int -> Array Int [a]
genElementaryPermutations1 :: forall a. (Ord a, Enum a, Num a) => Int -> Array Int [a]
genElementaryPermutations1 Int
n = (Int, Int) -> [[a]] -> Array Int [a]
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [[a]]
xs
  where
    xs :: [[a]]
xs = [a] -> [[a]]
forall a. (Ord a, Num a) => [a] -> [[a]]
pairsSwapP1 ([a] -> [[a]]) -> ([a] -> [a]) -> [a] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ [a
0 ..]
    l :: Int
l = [[a]] -> Int
forall a. [a] -> Int
length [[a]]
xs
{-# INLINE genElementaryPermutations1 #-}
{-# SPECIALIZE genElementaryPermutations1 :: Int -> Array Int [Int] #-}

pairsSwapP1 :: (Ord a, Num a) => [a] -> [[a]]
pairsSwapP1 :: forall a. (Ord a, Num a) => [a] -> [[a]]
pairsSwapP1 [a]
xs =
    [a]
xs
        [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: [a -> a -> [a] -> [a]
forall a. (Ord a, Num a) => a -> a -> [a] -> [a]
swap2Ls1 a
k a
m [a]
xs | a
k <- [a]
xs, a
m <- [a]
xs, a -> a
forall a. Num a => a -> a
abs (a
k a -> a -> a
forall a. Num a => a -> a -> a
- a
m) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1]
            [[a]] -> [[a]] -> [[a]]
forall a. Monoid a => a -> a -> a
`mappend` [a -> a -> [a] -> [a]
forall a. (Ord a, Num a) => a -> a -> [a] -> [a]
swap2Ls1 a
k (a
k a -> a -> a
forall a. Num a => a -> a -> a
- a
1) [a]
xs | a
k <- Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
1 [a]
xs]
{-# SPECIALIZE pairsSwapP1 :: [Int] -> [[Int]] #-}

-- | The first two arguments are considered not equal and all three of the arguments are considered greater or equal to 0, though it is not checked.
swap2ns1 :: (Ord a, Num a) => a -> a -> a -> a
swap2ns1 :: forall a. (Ord a, Num a) => a -> a -> a -> a
swap2ns1 a
k a
n a
m
    | a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
k =
        if
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
k -> a
m
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
n -> a
m
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
n -> a
m a -> a -> a
forall a. Num a => a -> a -> a
+ a
1
            | Bool
otherwise -> a
k
    | Bool
otherwise =
        if
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
k -> a
m
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
n -> a
m
            | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
n -> a
m a -> a -> a
forall a. Num a => a -> a -> a
- a
1
            | Bool
otherwise -> a
k
{-# INLINE swap2ns1 #-}
{-# SPECIALIZE swap2ns1 :: Int -> Int -> Int -> Int #-}

swap2Ls1 :: (Ord a, Num a) => a -> a -> [a] -> [a]
swap2Ls1 :: forall a. (Ord a, Num a) => a -> a -> [a] -> [a]
swap2Ls1 a
k a
m = (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a -> a -> a -> a
forall a. (Ord a, Num a) => a -> a -> a -> a
swap2ns1 a
k a
m)
{-# INLINE swap2Ls1 #-}
{-# SPECIALIZE swap2Ls1 :: Int -> Int -> [Int] -> [Int] #-}

genElementaryPermutationsArrN1 ::
    (Ord a, Enum a, Num a) => Int -> Array Int (Array Int [a])
genElementaryPermutationsArrN1 :: forall a.
(Ord a, Enum a, Num a) =>
Int -> Array Int (Array Int [a])
genElementaryPermutationsArrN1 Int
n = (Int -> Array Int [a])
-> Array Int Int -> Array Int (Array Int [a])
forall a b i. (a -> b) -> Array i a -> Array i b
amap Int -> Array Int [a]
forall a. (Ord a, Enum a, Num a) => Int -> Array Int [a]
genElementaryPermutations1 (Array Int Int -> Array Int (Array Int [a]))
-> ([Int] -> Array Int Int) -> [Int] -> Array Int (Array Int [a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> [Int] -> Array Int Int
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) ([Int] -> Array Int (Array Int [a]))
-> [Int] -> Array Int (Array Int [a])
forall a b. (a -> b) -> a -> b
$ [Int
2 .. Int
n]
{-# INLINE genElementaryPermutationsArrN1 #-}
{-# SPECIALIZE genElementaryPermutationsArrN1 ::
    Int -> Array Int (Array Int [Int])
    #-}

genElementaryPermutationsArr1 ::
    (Ord a, Enum a, Num a) => Array Int (Array Int [a])
genElementaryPermutationsArr1 :: forall a. (Ord a, Enum a, Num a) => Array Int (Array Int [a])
genElementaryPermutationsArr1 = Int -> Array Int (Array Int [a])
forall a.
(Ord a, Enum a, Num a) =>
Int -> Array Int (Array Int [a])
genElementaryPermutationsArrN1 Int
10
{-# INLINE genElementaryPermutationsArr1 #-}
{-# SPECIALIZE genElementaryPermutationsArr1 :: Array Int (Array Int [Int]) #-}

genElementaryPermutationsLN1 :: (Ord a, Enum a, Num a) => Int -> [Array Int a]
genElementaryPermutationsLN1 :: forall a. (Ord a, Enum a, Num a) => Int -> [Array Int a]
genElementaryPermutationsLN1 Int
n = ([a] -> Array Int a) -> [[a]] -> [Array Int a]
forall a b. (a -> b) -> [a] -> [b]
map (\[a]
xs -> (Int, Int) -> [a] -> Array Int a
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [a]
xs) ([[a]] -> [Array Int a]) -> ([a] -> [[a]]) -> [a] -> [Array Int a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [[a]]
forall a. (Ord a, Num a) => [a] -> [[a]]
pairsSwapP1 ([a] -> [[a]]) -> ([a] -> [a]) -> [a] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n ([a] -> [Array Int a]) -> [a] -> [Array Int a]
forall a b. (a -> b) -> a -> b
$ [a
0 ..]
{-# INLINE genElementaryPermutationsLN1 #-}
{-# SPECIALIZE genElementaryPermutationsLN1 :: Int -> [Array Int Int] #-}

genElementaryPermutationsL1 :: (Ord a, Enum a, Num a) => [Array Int a]
genElementaryPermutationsL1 :: forall a. (Ord a, Enum a, Num a) => [Array Int a]
genElementaryPermutationsL1 = Int -> [Array Int a]
forall a. (Ord a, Enum a, Num a) => Int -> [Array Int a]
genElementaryPermutationsLN1 Int
10
{-# INLINE genElementaryPermutationsL1 #-}
{-# SPECIALIZE genElementaryPermutationsL1 :: [Array Int Int] #-}

genElementaryPermutationsArrLN1 ::
    (Ord a, Enum a, Num a) => Int -> Array Int [Array Int a]
genElementaryPermutationsArrLN1 :: forall a. (Ord a, Enum a, Num a) => Int -> Array Int [Array Int a]
genElementaryPermutationsArrLN1 Int
n = (Int -> [Array Int a]) -> Array Int Int -> Array Int [Array Int a]
forall a b i. (a -> b) -> Array i a -> Array i b
amap Int -> [Array Int a]
forall a. (Ord a, Enum a, Num a) => Int -> [Array Int a]
genElementaryPermutationsLN1 (Array Int Int -> Array Int [Array Int a])
-> ([Int] -> Array Int Int) -> [Int] -> Array Int [Array Int a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> [Int] -> Array Int Int
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) ([Int] -> Array Int [Array Int a])
-> [Int] -> Array Int [Array Int a]
forall a b. (a -> b) -> a -> b
$ [Int
2 .. Int
n]
{-# INLINE genElementaryPermutationsArrLN1 #-}
{-# SPECIALIZE genElementaryPermutationsArrLN1 ::
    Int -> Array Int [Array Int Int]
    #-}

genElementaryPermutationsArrL1 ::
    (Ord a, Enum a, Num a) => Array Int [Array Int a]
genElementaryPermutationsArrL1 :: forall a. (Ord a, Enum a, Num a) => Array Int [Array Int a]
genElementaryPermutationsArrL1 = Int -> Array Int [Array Int a]
forall a. (Ord a, Enum a, Num a) => Int -> Array Int [Array Int a]
genElementaryPermutationsArrLN1 Int
10
{-# INLINE genElementaryPermutationsArrL1 #-}
{-# SPECIALIZE genElementaryPermutationsArrL1 :: Array Int [Array Int Int] #-}