module Ribosome.Data.List where

import qualified Data.Set as Set (difference, fromList, toList)

mapSelectors :: (a -> a) -> [Int] -> [a] -> [a]
mapSelectors :: (a -> a) -> [Int] -> [a] -> [a]
mapSelectors a -> a
f [Int]
indexes =
  [a] -> [a]
forall a. [a] -> [a]
reverse ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [a] -> [a] -> [a]
go Int
0 ([Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort [Int]
indexes) []
  where
    go :: Int -> [Int] -> [a] -> [a] -> [a]
go Int
current (Int
i : [Int]
is) [a]
result (a
a : [a]
asTail) | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
current =
      Int -> [Int] -> [a] -> [a] -> [a]
go (Int
current Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Int]
is (a -> a
f a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
result) [a]
asTail
    go Int
current [Int]
is [a]
result (a
a : [a]
asTail) =
      Int -> [Int] -> [a] -> [a] -> [a]
go (Int
current Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Int]
is (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
result) [a]
asTail
    go Int
_ [Int]
_ [a]
result [a]
_ =
      [a]
result

indexesComplement :: Int -> [Int] -> [Int]
indexesComplement :: Int -> [Int] -> [Int]
indexesComplement Int
total =
 Set Int -> [Int]
forall a. Set a -> [a]
Set.toList (Set Int -> [Int]) -> ([Int] -> Set Int) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set Int -> Set Int -> Set Int
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set Int
allIndexes (Set Int -> Set Int) -> ([Int] -> Set Int) -> [Int] -> Set Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Set Int
forall a. Ord a => [a] -> Set a
Set.fromList
  where
    allIndexes :: Set Int
allIndexes =
      [Int] -> Set Int
forall a. Ord a => [a] -> Set a
Set.fromList [Item [Int]
0..Int
total Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]