haskell: add simple run harness
This commit is contained in:
parent
a3c6a1d70c
commit
1e30302115
4 changed files with 26 additions and 26 deletions
|
@ -1,4 +1,4 @@
|
||||||
{-# LANGUAGE TypeApplications #-}
|
import AoC
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
@ -7,6 +7,5 @@ import Control.Monad
|
||||||
find_n_summing :: (Num a, Eq a) => a -> Int -> [a] -> Maybe [a]
|
find_n_summing :: (Num a, Eq a) => a -> Int -> [a] -> Maybe [a]
|
||||||
find_n_summing to = (find ((to ==) . sum) .) . replicateM
|
find_n_summing to = (find ((to ==) . sum) .) . replicateM
|
||||||
|
|
||||||
main = do
|
main = runAoC (fmap read <$> lines) (solution 2) (solution 3)
|
||||||
nums <- fmap read <$> lines <$> readFile "input.txt"
|
where solution = product . fromJust .: find_n_summing 2020
|
||||||
mapM_ print $ product <$> fromJust <$> flip (find_n_summing 2020) nums <$> [2, 3]
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import AoC
|
||||||
|
|
||||||
import Control.Applicative (empty)
|
import Control.Applicative (empty)
|
||||||
import Control.Monad.Zip (mzip)
|
import Control.Monad.Zip (mzip)
|
||||||
import Data.List (intercalate)
|
import Data.List (intercalate)
|
||||||
|
@ -6,9 +8,8 @@ import Data.Maybe (catMaybes)
|
||||||
compose2 :: (a' -> b' -> c) -> (a -> a') -> (b -> b') -> a -> b -> c
|
compose2 :: (a' -> b' -> c) -> (a -> a') -> (b -> b') -> a -> b -> c
|
||||||
compose2 f g h x y = f (g x) (h y)
|
compose2 f g h x y = f (g x) (h y)
|
||||||
|
|
||||||
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
|
(??) :: Functor f => f (a -> b) -> a -> f b
|
||||||
f .: g = (f .) . g
|
f ?? x = fmap ($ x) f
|
||||||
infixl 8 .:
|
|
||||||
|
|
||||||
countHits :: (Int, Int) -> [[Bool]] -> Int
|
countHits :: (Int, Int) -> [[Bool]] -> Int
|
||||||
countHits = length . filterMap lookup . catMaybes .: compose2 (zipWith mzip) maybeIndices justLines
|
countHits = length . filterMap lookup . catMaybes .: compose2 (zipWith mzip) maybeIndices justLines
|
||||||
|
@ -22,8 +23,6 @@ countHits = length . filterMap lookup . catMaybes .: compose2 (zipWith mzip) may
|
||||||
treeCharToBool :: Char -> Bool
|
treeCharToBool :: Char -> Bool
|
||||||
treeCharToBool = (== '#')
|
treeCharToBool = (== '#')
|
||||||
|
|
||||||
main = do
|
main = runAoC (fmap (cycle . map treeCharToBool) <$> lines) part1 part2
|
||||||
charLines <- lines <$> readFile "input.txt"
|
where part1 = countHits (3, 1)
|
||||||
let boolLines = cycle <$> map treeCharToBool <$> charLines
|
part2 = product . (fmap countHits [(1,1), (3,1), (5,1), (7,1), (1,2)] ??)
|
||||||
print $ countHits (3, 1) boolLines
|
|
||||||
print $ product $ flip countHits boolLines <$> [(1,1), (3,1), (5,1), (7,1), (1,2)]
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import AoC
|
||||||
|
|
||||||
import Control.Applicative ((<|>))
|
import Control.Applicative ((<|>))
|
||||||
import Control.Monad (guard, mfilter)
|
import Control.Monad (guard, mfilter)
|
||||||
import Data.Char (isDigit)
|
import Data.Char (isDigit)
|
||||||
|
@ -39,10 +41,6 @@ fieldSpecs = [ ("byr", BirthYear <$> parseYearIn 1920 2002)
|
||||||
where parseYearIn = flip mfilter (parseNumber 4) .: within
|
where parseYearIn = flip mfilter (parseNumber 4) .: within
|
||||||
parseHexDigit = choice . map char $ ['0'..'9']++['a'..'f']
|
parseHexDigit = choice . map char $ ['0'..'9']++['a'..'f']
|
||||||
|
|
||||||
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
|
|
||||||
f .: g = (f .) . g
|
|
||||||
infixl 8 .:
|
|
||||||
|
|
||||||
within :: Ord a => a -> a -> a -> Bool
|
within :: Ord a => a -> a -> a -> Bool
|
||||||
within a b x = a <= x && x <= b
|
within a b x = a <= x && x <= b
|
||||||
|
|
||||||
|
@ -92,7 +90,7 @@ parsePassport :: ReadP [Field]
|
||||||
parsePassport = spaceSeparated parseField
|
parsePassport = spaceSeparated parseField
|
||||||
|
|
||||||
oneCompleteResult :: ReadP a -> String -> Maybe a
|
oneCompleteResult :: ReadP a -> String -> Maybe a
|
||||||
oneCompleteResult p s = case readP_to_S p s of
|
oneCompleteResult p s = case readP_to_S (p <* eof) s of
|
||||||
[(x, "")] -> Just x
|
[(x, "")] -> Just x
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
|
@ -103,13 +101,6 @@ hasAllRequiredFields :: String -> Bool
|
||||||
hasAllRequiredFields = maybe False containsAllFields . fieldNames
|
hasAllRequiredFields = maybe False containsAllFields . fieldNames
|
||||||
where requiredFieldNames = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
|
where requiredFieldNames = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
|
||||||
containsAllFields fields = all (`elem` fields) requiredFieldNames
|
containsAllFields fields = all (`elem` fields) requiredFieldNames
|
||||||
fieldNames = oneCompleteResult (parseFieldNames <* eof)
|
fieldNames = oneCompleteResult parseFieldNames
|
||||||
|
|
||||||
main = do
|
main = runAoC (filter hasAllRequiredFields . splitOnEmptyLines) (length) (length . mapMaybe (oneCompleteResult parsePassport))
|
||||||
batches <- splitOnEmptyLines <$> readFile "input.txt"
|
|
||||||
|
|
||||||
let withRequiredFields = filter hasAllRequiredFields batches
|
|
||||||
print $ length withRequiredFields
|
|
||||||
|
|
||||||
let passports = mapMaybe (oneCompleteResult (parsePassport <* eof)) withRequiredFields
|
|
||||||
print $ length passports
|
|
||||||
|
|
11
common/AoC.hs
Normal file
11
common/AoC.hs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module AoC where
|
||||||
|
|
||||||
|
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
|
||||||
|
f .: g = (f .) . g
|
||||||
|
infixl 8 .:
|
||||||
|
|
||||||
|
runAoC :: (Show r1, Show r2) => (String -> i) -> (i -> r1) -> (i -> r2) -> IO ()
|
||||||
|
runAoC inputTransform part1 part2 = do
|
||||||
|
contents <- inputTransform <$> getContents
|
||||||
|
print $ part1 contents
|
||||||
|
print $ part2 contents
|
Loading…
Reference in a new issue