aboutsummaryrefslogtreecommitdiffstats
path: root/utils.hs
blob: c67fd07a5acb18f8497646f107429525bd4d7ffb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
module Utils where

import Control.Applicative (ZipList (ZipList, getZipList))
import Data.Char (digitToInt)

(.>) = flip (.)

($>) = flip ($)

infixr 6 $>

splitOn :: (a -> Bool) -> [a] -> [[a]]
splitOn p s = case dropWhile p s of
  [] -> []
  s' -> w : splitOn p s''
    where
      (w, s'') = break p s'

transpose :: [[a]] -> [[a]]
transpose = getZipList . traverse ZipList

mapWithIndex :: (a -> b) -> [a] -> [(Int, b)]
mapWithIndex f xs = zip [0 ..] (map f xs)

removeAt :: [Int] -> [b] -> [b]
removeAt is xs = mapWithIndex id xs $> filter (\(i', _) -> i' `notElem` is) .> map snd

slice :: Int -> Int -> [a] -> [a]
slice from to xs = take (to - from + 1) (drop from xs)

splitEvery _ [] = []
splitEvery n list = first : splitEvery n rest
  where
    (first, rest) = splitAt n list

splitToPair :: (Show a) => (a -> Bool) -> [a] -> ([a], [a])
splitToPair f lst =
  let x' = takeWhile (not . f) lst
      y' = dropWhile (not . f) lst $> drop 1
   in (x', y')

count :: (a -> Bool) -> [a] -> Int
count pred xs = xs $> filter pred .> length

takeUntil :: (a -> Bool) -> [a] -> [a]
takeUntil _ [] = []
takeUntil p (x : xs) = x : if p x then takeUntil p xs else []

fromSymEither (Left x) = x
fromSymEither (Right x) = x

-- | Convert binary (list of zeros and ones) to decimal
binaryToInt :: String -> Int
binaryToInt = reverse .> binaryToIntRev

binaryToIntRev [] = 0
binaryToIntRev (x : xs) = digitToInt x + 2 * binaryToIntRev xs