module Utils (readInt, toBin, toDec, leftPad, chunksOf, count, consecutiveChunksOf, leftUnpad, rightPad) where

import Data.Char (digitToInt, intToDigit)
import Data.List (foldl')
import Numeric (showIntAtBase)
import Kewar.Types (BitString)

readInt :: String -> Int
readInt :: String -> Int
readInt = String -> Int
forall a. Read a => String -> a
read

toBin :: Int -> BitString
toBin :: Int -> String
toBin Int
n = Int -> (Int -> Char) -> Int -> ShowS
forall a. (Integral a, Show a) => a -> (Int -> Char) -> a -> ShowS
showIntAtBase Int
2 Int -> Char
intToDigit Int
n String
""

toDec :: BitString -> Int
toDec :: String -> Int
toDec = (Int -> Char -> Int) -> Int -> String -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
acc Char
v -> Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Char -> Int
digitToInt Char
v) Int
0

leftPad :: Int -> Char -> String -> String
leftPad :: Int -> Char -> ShowS
leftPad Int
size Char
char String
str = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str) Char
char String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
str

rightPad :: Int -> Char -> String -> String
rightPad :: Int -> Char -> ShowS
rightPad Int
size Char
char String
str = String
str String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str) Char
char

leftUnpad :: Char -> String -> String
leftUnpad :: Char -> ShowS
leftUnpad Char
char = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
char)

count :: (a -> Bool) -> [a] -> Int
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
predicate = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
predicate

consecutiveChunksOf :: Int -> [a] -> [[a]]
consecutiveChunksOf :: Int -> [a] -> [[a]]
consecutiveChunksOf Int
n [a]
l = [(Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
i) [a]
l | Int
i <- [Int
0 .. ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)]]

chunksOf :: Int -> [a] -> [[a]]
chunksOf :: Int -> [a] -> [[a]]
chunksOf Int
n [a]
l = Int -> [a] -> [[a]] -> [[a]]
forall a. Int -> [a] -> [[a]] -> [[a]]
step Int
n [a]
l []
  where
    step :: Int -> [a] -> [[a]] -> [[a]]
step Int
size [a]
list [[a]]
acc = do
      if [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
list Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
size
        then [[a]]
acc [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ [[a]
list]
        else do
          let ([a]
chunk, [a]
rest) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
size [a]
list
          Int -> [a] -> [[a]] -> [[a]]
step Int
size [a]
rest ([[a]]
acc [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ [[a]
chunk])