import Data.Bits import Data.Char import Data.List main :: IO () main = do input <- lines <$> readFile "input" let rating = take (length $ head input) $ transpose (map tails input) let [gamma, epsilon] = [toDec $ map (commonBit f) rating | f <- [(<=), (>)]] print $ gamma * epsilon let part2 = [genRating x input [] | x <- [(<=), (>)]] print $ product $ map toDec part2 commonBit :: (Int -> Int -> Bool) -> [String] -> Int commonBit f = (\[x, y] -> fromEnum (x `f` y)) . map (length) . group . sort . head . transpose genRating :: (Int -> Int -> Bool) -> [String] -> [Int] -> [Int] genRating _ (x:[]) acc = acc ++ (map digitToInt x) genRating f input acc = genRating f (map tail $ filter (isPrefixOf (show $ commonBit f input)) input) (acc ++ [commonBit f input]) toDec :: [Int] -> Int toDec = sum . map (uncurry (*)) . zip (map bit [0 ..]) . reverse