{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_HADDOCK -show-extensions #-}

{- |
Module      :  Aftovolio.Halfsplit
Copyright   :  (c) OleksandrZhabenko 2023, 2025
License     :  MIT
Stability   :  Experimental
Maintainer  :  oleksandr.zhabenko@yahoo.com
-}
module Aftovolio.Halfsplit where

import Data.Char (isDigit)
import Data.List hiding (foldr)
import Data.Lists.FLines (newLineEnding)
import Data.Tuple (fst)
import GHC.Base
import GHC.Enum (fromEnum)
import GHC.Int (Int8)
import GHC.Num (abs, (+), (-))
import GHC.Real (quot, quotRem, odd)
import System.IO (getLine, putStr, putStrLn)
import Text.Read (readMaybe)
import Data.Maybe (Maybe,fromMaybe)
import Text.Show (Show (..))
--import Debug.Trace

-- | Converts the data that is an instance of 'Show' typeclass to be printed in two-column way.
halfsplit ::
    (Show a, Eq b) =>
    (a -> b) ->
    -- | Whether to filter out all groups of \'={digits}\' from the lines.
    Bool ->
    Int8 ->
    [a] ->
    String
halfsplit :: forall a b.
(Show a, Eq b) =>
(a -> b) -> Bool -> Int8 -> [a] -> String
halfsplit a -> b
g Bool
filtering = (a -> b) -> Bool -> String -> Int8 -> [a] -> String
forall a b.
(Show a, Eq b) =>
(a -> b) -> Bool -> String -> Int8 -> [a] -> String
halfsplit1G a -> b
g Bool
filtering String
""
{-# INLINE halfsplit #-}

{- | Converts the data that is an instance of 'Show' typeclass to be printed in two-column way with
customizable ending of each line. Filters out all groups of \'={digits}\' from the lines.
-}
halfsplit1G ::
    (Show a, Eq b) =>
    (a -> b) ->
    -- | Whether to filter out all groups of \'={digits}\' from the lines.
    Bool ->
    -- | Additional 'String' added to every line before the newline character.
    String ->
    Int8 ->
    [a] ->
    String
halfsplit1G :: forall a b.
(Show a, Eq b) =>
(a -> b) -> Bool -> String -> Int8 -> [a] -> String
halfsplit1G a -> b
g Bool
filtering String
appendstr Int8
m [a]
xs
    | [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
xs = []
    | Bool
otherwise =
        let (Int
n, Int
rr2) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
quotRem (Int8 -> Int
forall a. Enum a => a -> Int
fromEnum Int8
m) (if Int8
m Int8 -> Int8 -> Bool
forall a. Ord a => a -> a -> Bool
< Int8
0 then -Int
10 else Int
10)
            rr3 :: Int
rr3 = Int -> Int
forall a. Num a => a -> a
abs Int
rr2
            noChange :: Bool
noChange = Int -> Bool
forall a. Integral a => a -> Bool
odd Int
rr3
            l0 :: Int
l0 = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> Int) -> ([a] -> String) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> a -> String
forall a. Show a => Bool -> a -> String
showFiltering Bool
filtering (a -> String) -> ([a] -> a) -> [a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> a
forall a. HasCallStack => [a] -> a
head ([a] -> Int) -> [a] -> Int
forall a b. (a -> b) -> a -> b
$ [a]
xs -- For empty lines
            r :: ([String], [String])
r 
              | Int
rr3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Bool -> Bool -> Bool
&& Int
rr3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
6 = (Bool -> [String] -> [String]
forall a. Bool -> [a] -> [a]
noChangeReverse Bool
noChange [String]
ws, Bool -> [String] -> [String]
forall a. Bool -> [a] -> [a]
noChangeReverse (Bool -> Bool
not Bool
noChange) [String]
w2s)
              | Bool
otherwise = Bool -> Bool -> Int -> [a] -> ([String], [String])
forall a.
Show a =>
Bool -> Bool -> Int -> [a] -> ([String], [String])
splitTwoBasic Bool
filtering (Int
rr3 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1) Int
l0 [a]
xs
                 where ([String]
ws,[String]
w2s) = Bool -> Bool -> Int -> (a -> b) -> [a] -> ([String], [String])
forall a b.
(Show a, Eq b) =>
Bool -> Bool -> Int -> (a -> b) -> [a] -> ([String], [String])
splitTwo Bool
filtering (Int
rr3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
3) Int
l0 a -> b
g [a]
xs
         in ((\([String]
rs, [String]
qs) -> Int -> String -> [String] -> [String] -> String
mergePartsLine Int
n (String
appendstr String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
newLineEnding) [String]
rs [String]
qs) ([String], [String])
r)
                    String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
appendstr

showFiltering 
  :: (Show a) 
  => Bool
  -> a
  -> String
showFiltering :: forall a. Show a => Bool -> a -> String
showFiltering Bool
filtering = (if Bool
filtering then String -> String
removeChangesOfDurations else String -> String
forall a. a -> a
id) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
{-# INLINE showFiltering #-}  

splitTwoBasic 
  :: (Show a) => Bool
  -> Bool
  -> Int 
  -> [a]
  -> ([String],[String])
splitTwoBasic :: forall a.
Show a =>
Bool -> Bool -> Int -> [a] -> ([String], [String])
splitTwoBasic Bool
filtering Bool
first Int
l0 [a]
xs = ((if Int
rrr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [String] -> [String]
forall a. a -> a
id else (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
l0 Char
' ' String -> [String] -> [String]
forall a. a -> [a] -> [a]
:)) ([String] -> [String]) -> ([a] -> [String]) -> [a] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> a -> String
forall a. Show a => Bool -> a -> String
showFiltering Bool
filtering) ([a] -> [String]) -> ([a] -> [a]) -> [a] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [a] -> [a]
forall a. Bool -> [a] -> [a]
noChangeReverse Bool
first ([a] -> [String]) -> [a] -> [String]
forall a b. (a -> b) -> a -> b
$ [a]
ys, (a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> a -> String
forall a. Show a => Bool -> a -> String
showFiltering Bool
filtering) ([a] -> [String]) -> ([a] -> [a]) -> [a] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [a] -> [a]
forall a. Bool -> [a] -> [a]
noChangeReverse (Bool -> Bool
not Bool
first) ([a] -> [String]) -> [a] -> [String]
forall a b. (a -> b) -> a -> b
$ [a]
ts)
  where
    ([a]
ys, [a]
ts) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
l [a]
xs -- Is used for basic splitting
    (Int
l, Int
rrr) = [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
2 -- For basic splitting
{-# INLINABLE splitTwoBasic #-}

noChangeF 
  :: Bool
  -> ([a] -> [a])
  -> [a]
  -> [a]
noChangeF :: forall a. Bool -> ([a] -> [a]) -> [a] -> [a]
noChangeF Bool
nochange [a] -> [a]
f [a]
xs = if Bool
nochange then [a]
xs else [a] -> [a]
f [a]
xs
{-# INLINE noChangeF #-}
    
noChangeReverse 
  :: Bool 
  -> [a]
  -> [a]
noChangeReverse :: forall a. Bool -> [a] -> [a]
noChangeReverse Bool
nochange = Bool -> ([a] -> [a]) -> [a] -> [a]
forall a. Bool -> ([a] -> [a]) -> [a] -> [a]
noChangeF Bool
nochange ([a] -> [a]
forall a. [a] -> [a]
reverse)
{-# INLINE noChangeReverse #-}

splitTwo 
  :: (Show a, Eq b) 
  -- | Whether to filter out all groups of \'={digits}\' from the lines.
  => Bool
  -> Bool
  -> Int
  -> (a -> b) 
  -> [a] 
  -> ([String],[String])
splitTwo :: forall a b.
(Show a, Eq b) =>
Bool -> Bool -> Int -> (a -> b) -> [a] -> ([String], [String])
splitTwo Bool
filtering Bool
emptyline Int
l0 a -> b
g [a]
xs = ([String]
y10s, [String]
t10s) 
  where
    rss :: [[String]]
rss = (if Bool
emptyline then [String] -> [[String]] -> [[String]]
forall a. a -> [a] -> [a]
intersperse [String
""] else [[String]] -> [[String]]
forall a. a -> a
id) ([[String]] -> [[String]])
-> ([a] -> [[String]]) -> [a] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [String]) -> [[a]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> a -> String
forall a. Show a => Bool -> a -> String
showFiltering Bool
filtering)) ([[a]] -> [[String]]) -> ([a] -> [[a]]) -> [a] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> Bool) -> [a] -> [[a]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\a
x a
y -> a -> b
g a
x b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== a -> b
g a
y) ([a] -> [[String]]) -> [a] -> [[String]]
forall a b. (a -> b) -> a -> b
$ [a]
xs
    (Int
l2, Int
r20) = ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> ([[String]] -> [Int]) -> [[String]] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> Int) -> [[String]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[String]] -> Int) -> [[String]] -> Int
forall a b. (a -> b) -> a -> b
$ [[String]]
rss) Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
2
    ([String]
y100s, [String]
t10s) = Int -> [String] -> ([String], [String])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
l2 ([String] -> ([String], [String]))
-> ([[String]] -> [String]) -> [[String]] -> ([String], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[String]] -> ([String], [String]))
-> [[String]] -> ([String], [String])
forall a b. (a -> b) -> a -> b
$ [[String]]
rss
    y10s :: [String]
y10s 
        | Int
r20 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = [String]
y100s
        | Bool
otherwise = String
""String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
y100s
{-# INLINABLE splitTwo #-}

-- | A generalized version of 'halfsplit3G' with the possibility to prepend and append strings to it. These 'String's are not filtered out for the groups of \'={digits}\' from the prepending and appending 'String's.
halfsplit2G ::
    (Show a, Eq b) =>
    (a -> b) ->
    -- | Whether to filter out all groups of \'={digits}\' from the lines.
    Bool ->
    -- | Additional 'String' added to every line before the newline character.
    String ->
    -- | A 'String' that is prepended to the 'halfsplit1G' result.
    String ->
    -- | A 'String' that is appended to the 'halfsplit1G' result.
    String ->
    Int8 ->
    [a] ->
    String
halfsplit2G :: forall a b.
(Show a, Eq b) =>
(a -> b)
-> Bool -> String -> String -> String -> Int8 -> [a] -> String
halfsplit2G a -> b
g Bool
filtering String
appendstr String
prestr String
poststr Int8
m [a]
xs = String
prestr String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` (a -> b) -> Bool -> String -> Int8 -> [a] -> String
forall a b.
(Show a, Eq b) =>
(a -> b) -> Bool -> String -> Int8 -> [a] -> String
halfsplit1G a -> b
g Bool
filtering String
appendstr Int8
m [a]
xs String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
poststr
{-# INLINABLE halfsplit2G #-}

-- | Filters out all groups of \"={digits}\" and \"_{digits}\" from the 'String'
removeChangesOfDurations :: String -> String
removeChangesOfDurations :: String -> String
removeChangesOfDurations (Char
'=' : String
xs) = String -> String
removeChangesOfDurations ((Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isDigit String
xs)
removeChangesOfDurations (Char
'_' : String
xs) = String -> String
removeChangesOfDurations ((Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isDigit String
xs) -- added since aftovolio-0.8.0.0
removeChangesOfDurations (Char
x : String
xs) = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
removeChangesOfDurations String
xs
removeChangesOfDurations String
_ = []

mergePartsLine :: Int -> String -> [String] -> [String] -> String
mergePartsLine :: Int -> String -> [String] -> [String] -> String
mergePartsLine Int
n String
newlined [String]
xs [String]
ys =
    String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
newlined
        ([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  String -> [String] -> [String] -> [String]
showWithSpacesBefore (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Char
'\t' else Char
' ')) [String]
xs ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [String]
ys

splitGroups :: Int -> [[a]] -> ([[a]], [[a]], Int)
splitGroups :: forall a. Int -> [[a]] -> ([[a]], [[a]], Int)
splitGroups Int
l [[a]]
tss = ([a] -> ([[a]], [[a]], Int) -> ([[a]], [[a]], Int))
-> ([[a]], [[a]], Int) -> [[a]] -> ([[a]], [[a]], Int)
forall a b. (a -> b -> b) -> b -> [a] -> b
foldr [a] -> ([[a]], [[a]], Int) -> ([[a]], [[a]], Int)
forall {t :: * -> *} {a}.
Foldable t =>
t a -> ([t a], [t a], Int) -> ([t a], [t a], Int)
h ([], [], Int
0) [[a]]
tss
  where
    h :: t a -> ([t a], [t a], Int) -> ([t a], [t a], Int)
h t a
js ([t a]
rss, [t a]
mss, Int
k)
        | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l = ([t a]
rss, t a
js t a -> [t a] -> [t a]
forall a. a -> [a] -> [a]
: [t a]
mss, Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
js)
        | Bool
otherwise = (t a
js t a -> [t a] -> [t a]
forall a. a -> [a] -> [a]
: [t a]
rss, [t a]
mss, Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
js)

showWithSpaces :: (Show a) => Int -> a -> String
showWithSpaces :: forall a. Show a => Int -> a -> String
showWithSpaces Int
n a
x
    | Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = String
xs String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l) Char
' '
    | Bool
otherwise = String
xs
  where
    xs :: String
xs = a -> String
forall a. Show a => a -> String
show a
x
    l :: Int
l = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xs

showWithSpacesBefore 
  :: String 
  -> [String] 
  -> [String] 
  -> [String]
showWithSpacesBefore :: String -> [String] -> [String] -> [String]
showWithSpacesBefore String
inserts (String
ts:String
xs:[String]
xss) (String
us:String
ys:[String]
yss) 
  | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
xs = String
ws String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Int -> Char -> String
forall a. Int -> a -> [a]
replicate (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
ts) Char
' ' String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
inserts String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
ys) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [String] -> [String] -> [String]
showWithSpacesBefore String
inserts [String]
xss [String]
yss
  | Bool
otherwise = String
ws String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [String] -> [String] -> [String]
showWithSpacesBefore String
inserts (String
xsString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
xss) (String
ysString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
yss)
    where ws :: String
ws = String
ts String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
inserts String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
us
showWithSpacesBefore String
inserts [String
xs] (String
ys:[String]
_) = [(if String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
xs then Int -> Char -> String
forall a. Int -> a -> [a]
replicate (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
ys) Char
' ' else String
xs) String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
inserts String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
ys]
showWithSpacesBefore String
inserts [String]
_ [String]
_ = []

print23 :: Bool -> String -> String -> Int -> [String] -> IO ()
print23 :: Bool -> String -> String -> Int -> [String] -> IO ()
print23 Bool
filtering String
prestr String
poststr Int
n [String]
xss = do
    String -> IO ()
putStrLn String
prestr
    let linez :: [(String, Int)]
linez = [String] -> [Int] -> [(String, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [String]
xss [Int
1 ..]
    if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        then do
            let linez3 :: [String]
linez3 =
                    (\(String
x : String
y : String
t : [String]
xs) -> String
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Char
' ' Char -> String -> String
forall a. a -> [a] -> [a]
: String
y) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Char
' ' Char -> String -> String
forall a. a -> [a] -> [a]
: Char
' ' Char -> String -> String
forall a. a -> [a] -> [a]
: String
t) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
xs)
                        ([String] -> [String])
-> ([(String, Int)] -> [String]) -> [(String, Int)] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst
                        ([(String, Int)] -> [String])
-> ([(String, Int)] -> [(String, Int)])
-> [(String, Int)]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int) -> Bool) -> [(String, Int)] -> [(String, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(String
ts, Int
m) -> Int
m Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 .. Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1]) ([(String, Int)] -> [String]) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> a -> b
$
                        [(String, Int)]
linez
            (String -> IO ()) -> [String] -> IO [()]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM String -> IO ()
putSLn [String]
linez3 IO [()] -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> IO ()
putStrLn String
poststr
        else
            ( case Int
n of
                Int
1 -> String -> IO ()
putStr String
" " IO () -> IO [()] -> IO [()]
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> IO ()) -> [String] -> IO [()]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM String -> IO ()
putSLn (Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
take Int
2 [String]
xss)
                Int
m ->
                    if Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
l
                        then (String -> IO ()) -> [String] -> IO [()]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM String -> IO ()
putSLn ((\(String
x : String
y : [String]
xs) -> String
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Char
' ' Char -> String -> String
forall a. a -> [a] -> [a]
: String
y) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
xs) ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
xss)
                        else [()] -> IO [()]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
            )
                IO [()] -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> IO ()
putStrLn String
poststr
  where
    l :: Int
l = [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
xss
    putSLn :: String -> IO ()
putSLn = String -> IO ()
putStrLn (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Bool
filtering then String -> String
removeChangesOfDurations else String -> String
forall a. a -> a
id)

readNums :: [String] -> [Int]
readNums :: [String] -> [Int]
readNums = (String -> [Int]) -> [String] -> [Int]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> [Int]
readNs
  where readNs :: String -> [Int]
        readNs :: String -> [Int]
readNs String
xs 
            | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-') String
xs = 
                 let (String
ys, String
ts) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-') String
xs 
                     us :: String
us = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit) String
ts
                 in [(Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe String
ys:: Maybe Int))..(Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe String
us:: Maybe Int))]
            | Bool
otherwise = [Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe String
xs:: Maybe Int)]
{-# INLINE readNums #-}