Advent of Code - 2021 - 3

Haskell

gamma l
  | l !! 0 == "" = []
  | a > b        = '0' : gamma cs 
  | otherwise    = '1' : gamma cs 
  where
    l' = map (splitAt 1) l
    c  = map fst l'
    cs = map snd l'
    a = length $ filter (== "0") c
    b = length $ filter (== "1") c

epsilon l = [if c == '0' then '1' else '0' | c <- gamma l]

bin2dec []     = 0
bin2dec (b:bs) = (if b == '1' then 2 ^ length bs else 0) + bin2dec bs

filter' :: Int -> (Int -> Int -> Bool) -> [String] -> String
filter' i op [e] = e
filter' i op l
  | op (length a) (length b) = filter' k op a
  | otherwise                = filter' k op b
  where
    k = i + 1
    a = [c | c <- l, c !! i == '0']
    b = [c | c <- l, c !! i == '1']

part1 = (\x -> (bin2dec $ gamma x) * (bin2dec $ epsilon x)) . lines

part2 = let f op = bin2dec . filter' 0 op
        in  (\x -> (f (>) x) * (f (<=) x)) . lines
    
main = readFile "input.txt" >>= \x -> print $ (part1 x, part2 x)