module Day3_1 where import System.IO (openFile, IOMode (ReadMode), hClose, hGetContents) import Data.List ( maximumBy, minimumBy, group, sort ) import Data.Function (on) import Data.Char (digitToInt) column :: [String] -> Int -> String column str i = map (!! i) str mostCommon :: String -> Char mostCommon str = head . maximumBy (compare `on` length) . group $ sort str leastCommon :: String -> Char leastCommon str = head . minimumBy (compare `on` length) . group $ sort str -- in: input strings, sorting method, current digit -- out: filtered strings filterColumns :: [String] -> (String -> Char) -> Int -> [String] filterColumns str sort i = filter (\a -> (a !! i) == commonChar) str where commonChar = sort $ column str i -- in: input strings, sorting method, current digit -- out: final rating rating :: [String] -> (String -> Char) -> Int -> String rating [str] _ _ = str rating str sort i = rating (filterColumns str sort i) sort (i+1) binaryToDecimal :: Int -> Int binaryToDecimal = foldl1 ((+) . (2 *)) . map digitToInt . show main :: IO () main = do input <- openFile "inputs/3.txt" ReadMode contents <- hGetContents input let oxygen = rating (lines contents) mostCommon 0 let co2 = rating (lines contents) leastCommon 0 let rating = product (binaryToDecimal . read <$> [oxygen, co2] :: [Int]) print rating hClose input