module DobutokO.Poetry.Norms (
norm1
, norm2
, norm3
, norm4
, norm5
, norm51
, norm513
, norm6
, splitNorm
) where
import qualified Data.Vector as V
import Data.List ((\\))
norm1 :: [Int] -> Int
norm1 xs
| null xs = 0
| otherwise = maximum xs
{-# INLINE norm1 #-}
norm2 :: [Int] -> Int
norm2 xs = sum xs
{-# INLINE norm2 #-}
norm3 :: [Int] -> Int
norm3 xs
| null xs = 0
| otherwise = maximum xs + sum xs
{-# INLINE norm3 #-}
norm4 :: [Int] -> Int
norm4 xs
| null xs = 0
| otherwise = maximum xs + sum xs + maximum (xs \\ [maximum xs])
{-# INLINE norm4 #-}
norm5 :: [Int] -> Int
norm5 xs
| null xs = 0
| minimum xs == 0 = norm5 . filter (/= 0) $ xs
| otherwise = sum xs `quot` (minimum xs + minimum (xs \\ [minimum xs]))
{-# INLINE norm5 #-}
norm51 :: [Int] -> Int
norm51 xs
| null xs = 0
| compare (minimum xs) 1 /= GT = let ys = filter (\t -> compare t 1 == GT) xs in (3 * sum xs) `quot` (minimum ys + minimum (ys \\ [minimum ys]))
| otherwise = (3 * sum xs) `quot` (minimum xs + minimum (xs \\ [minimum xs]))
{-# INLINE norm51 #-}
norm513 :: [Int] -> Int
norm513 xs
| null xs = 0
| compare (minimum xs) 1 /= GT =
let ys = filter (\t -> compare t 1 == GT) xs
zs = ys \\ [minimum ys] in (3 * sum xs) `quot` (minimum ys + minimum zs + minimum (zs \\ [minimum zs]))
| otherwise =
let zs = xs \\ [minimum xs] in (3 * sum xs) `quot` (minimum xs + minimum zs + minimum (zs \\ [minimum zs]))
{-# INLINE norm513 #-}
norm6 :: [Int] -> Int
norm6 xs = floor (fromIntegral (norm5 xs * sum xs) / fromIntegral (norm3 xs))
{-# INLINE norm6 #-}
splitNorm :: [Int] -> V.Vector ([Int] -> Int) -> [Int]
splitNorm xs vN
| null (filter (/=0) xs) || V.length vN /= length (filter (== 0) xs) + 1 = []
| otherwise =
let (ys,zs) = break (== 0) xs
zzs = drop 1 zs
in (V.unsafeIndex vN (V.length vN - 1)) ys:splitNorm zzs (V.unsafeSlice 0 (V.length vN - 1) vN)