35 lines
1.1 KiB
Haskell
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 |