aoc2021/Day3_1.hs

45 lines
1.3 KiB
Haskell

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