From 555da2ae6f658672cfc0d37e437ec356c0c0fa63 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 5 Dec 2020 13:19:25 +0530 Subject: factor common functions into Utils --- aoc.cabal | 16 +++++++++++----- execs/Day02.hs | 7 +------ execs/Day04.hs | 17 +++++++---------- execs/Day05.hs | 9 ++++----- lib/Utils.hs | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 lib/Utils.hs diff --git a/aoc.cabal b/aoc.cabal index a5be71d..6690e58 100644 --- a/aoc.cabal +++ b/aoc.cabal @@ -16,32 +16,38 @@ maintainer: nerdy@peppe.rs build-type: Simple extra-source-files: CHANGELOG.md +library + hs-source-dirs: lib + default-language: Haskell2010 + build-depends: base + exposed-modules: Utils + executable Day01 main-is: Day01.hs - build-depends: base + build-depends: base, aoc default-language: Haskell2010 hs-source-dirs: execs executable Day02 main-is: Day02.hs - build-depends: base, parsec + build-depends: base, parsec, aoc default-language: Haskell2010 hs-source-dirs: execs executable Day03 main-is: Day03.hs - build-depends: base + build-depends: base, aoc default-language: Haskell2010 hs-source-dirs: execs executable Day04 main-is: Day04.hs - build-depends: base, parsec, containers + build-depends: base, parsec, containers, aoc default-language: Haskell2010 hs-source-dirs: execs executable Day05 main-is: Day05.hs - build-depends: base + build-depends: base, aoc default-language: Haskell2010 hs-source-dirs: execs diff --git a/execs/Day02.hs b/execs/Day02.hs index a2815b7..c462ec9 100644 --- a/execs/Day02.hs +++ b/execs/Day02.hs @@ -2,12 +2,7 @@ module Main where import Text.ParserCombinators.Parsec import Text.Parsec.Char - -countElem c ls = sum $ map (fromEnum . (== c)) ls - -xor a b = (not a && b) || (a && not b) - -right (Right a) = a +import Utils data PassProp = PassProp { range :: (Int, Int) diff --git a/execs/Day04.hs b/execs/Day04.hs index 565415f..a95dfd0 100644 --- a/execs/Day04.hs +++ b/execs/Day04.hs @@ -1,11 +1,11 @@ module Main where -import Text.ParserCombinators.Parsec -import Data.Map.Strict (Map, (!)) +import Text.ParserCombinators.Parsec +import Data.Map.Strict (Map, (!)) import qualified Data.Map.Strict as Map -import Data.Char (isDigit, isHexDigit) +import Data.Char (isDigit, isHexDigit) +import Utils -right (Right a) = a requiredFields = [ "byr" , "iyr" , "eyr" , "hgt" , "hcl" , "ecl" , "pid" ] eyeColors = ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"] @@ -22,9 +22,6 @@ parseInput s = Map.fromList <$> parse block "input" s doCheck :: Map String String -> Bool doCheck ls = all ((== True) . flip Map.member ls) requiredFields -bet :: Int -> (Int, Int) -> Bool -bet k (l, u) = k >= l && k <= u - validByr s = bet (read s :: Int) (1920, 2002) validIyr s = bet (read s :: Int) (2010, 2020) validEyr s = bet (read s :: Int) (2020, 2030) @@ -41,8 +38,8 @@ validHgt s = (v, "in") -> bet v (59, 76) _ -> False -doValidity :: Map String String -> Bool -doValidity map = all ((== True) . (\(s, v) -> v $ map ! s)) ls +doValidate :: Map String String -> Bool +doValidate map = all ((== True) . (\(s, v) -> v $ map ! s)) ls where ls = [ ("byr", validByr) , ("iyr", validIyr) , ("eyr", validEyr) @@ -64,4 +61,4 @@ main = do {- part 1 -} print $ length $ filter doCheck blocks {- part 2 -} - print $ length $ filter (\p -> doCheck p && doValidity p) blocks + print $ length $ filter (doCheck &+ doValidate) blocks diff --git a/execs/Day05.hs b/execs/Day05.hs index aae8f49..27397f7 100644 --- a/execs/Day05.hs +++ b/execs/Day05.hs @@ -1,12 +1,11 @@ module Main where import Data.Char (digitToInt) +import Utils (binaryToInt) -doValidate = toInt . map readBin -toInt = foldl (\a x -> a * 2 + digitToInt x) 0 -readBin 'F' = '0' -readBin 'L' = '0' -readBin _ = '1' +doValidate = binaryToInt . map readBin +readBin s | s `elem` "FL" = '0' + | otherwise = '1' main :: IO () main = do diff --git a/lib/Utils.hs b/lib/Utils.hs new file mode 100644 index 0000000..1eb42fc --- /dev/null +++ b/lib/Utils.hs @@ -0,0 +1,32 @@ +module Utils ( binaryToInt + , countElem + , xor + , right + , bet + , (&+) + ) where + +import Data.Char (digitToInt) +import Control.Monad +import Data.Either + + +binaryToInt :: String -> Int +binaryToInt = foldl (\a x -> a * 2 + digitToInt x) 0 + +countElem :: (Eq a) => a -> [a] -> Int +countElem c ls = sum $ map (fromEnum . (== c)) ls + +xor :: Bool -> Bool -> Bool +xor a b = (not a && b) || (a && not b) + +right :: Either a b -> b +right (Right b) = b +right _ = undefined + +bet :: Int -> (Int, Int) -> Bool +bet k (l, u) = k >= l && k <= u + +-- combine filter predicates +(&+) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool) +(&+) = liftM2 (&&) -- cgit v1.2.3