module Day03 where import Data.Char (digitToInt) import Data.List (foldl', transpose) count :: Eq a => a -> [a] -> Int count x = length . filter (x==) binToDec :: String -> Int binToDec = foldl' (\acc x -> acc * 2 + digitToInt x) 0 getMostCommon :: String -> Char getMostCommon x = if count '0' x > count '1' x then '0' else '1' getLeastCommon :: String -> Char getLeastCommon x = if count '0' x > count '1' x then '1' else '0' filterNumbers :: (String->Char) -> Int -> [String] -> String filterNumbers _ _ [x] = x filterNumbers f i nums = filterNumbers f (i+1) $ filter (\w -> w!!i == filterVal) nums where filterVal = f $ map (!!i) nums main :: IO () main = do input <- getContents let bits = lines input putStr "part 1: " let gamma = binToDec $ map getMostCommon $ transpose bits let epsilon = binToDec $ map getLeastCommon $ transpose bits print $ gamma*epsilon putStr "part 2: " let oxygen = binToDec $ filterNumbers getMostCommon 0 bits let co2 = binToDec $ filterNumbers getLeastCommon 0 bits print $ oxygen*co2