adventofcode/2021/day03.hs

35 lines
1.1 KiB
Haskell

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