|
|
@ -2,41 +2,45 @@ |
|
|
|
|
|
|
|
|
|
|
|
module Day2 (day2) where |
|
|
|
module Day2 (day2) where |
|
|
|
|
|
|
|
|
|
|
|
import qualified Data.Text as T |
|
|
|
|
|
|
|
import qualified Data.Attoparsec.Text as P |
|
|
|
import qualified Data.Attoparsec.Text as P |
|
|
|
import Data.List (elemIndices) |
|
|
|
import Data.List (elemIndices) |
|
|
|
|
|
|
|
import qualified Data.Text as T |
|
|
|
|
|
|
|
|
|
|
|
type Max = Int |
|
|
|
type Max = Int |
|
|
|
|
|
|
|
|
|
|
|
type Min = Int |
|
|
|
type Min = Int |
|
|
|
|
|
|
|
|
|
|
|
type Letter = Char |
|
|
|
type Letter = Char |
|
|
|
|
|
|
|
|
|
|
|
type Validator = Policy -> String -> Bool |
|
|
|
type Validator = Policy -> String -> Bool |
|
|
|
|
|
|
|
|
|
|
|
data Policy = Policy { lBound :: Min |
|
|
|
data Policy = Policy |
|
|
|
, uBound :: Max |
|
|
|
{ lBound :: Min, |
|
|
|
, letter :: Letter |
|
|
|
uBound :: Max, |
|
|
|
} |
|
|
|
letter :: Letter |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
parserPolicy :: P.Parser Policy |
|
|
|
parserPolicy :: P.Parser Policy |
|
|
|
parserPolicy = do |
|
|
|
parserPolicy = do |
|
|
|
lB <- P.decimal |
|
|
|
lB <- P.decimal |
|
|
|
_ <- P.char '-' |
|
|
|
_ <- P.char '-' |
|
|
|
uB <- P.decimal |
|
|
|
uB <- P.decimal |
|
|
|
_ <- P.char ' ' |
|
|
|
_ <- P.char ' ' |
|
|
|
le <- P.letter |
|
|
|
le <- P.letter |
|
|
|
_ <- P.string ": " |
|
|
|
_ <- P.string ": " |
|
|
|
return $ Policy lB uB le |
|
|
|
return $ Policy lB uB le |
|
|
|
|
|
|
|
|
|
|
|
validatePolicy :: Validator |
|
|
|
validatePolicy :: Validator |
|
|
|
validatePolicy p s = |
|
|
|
validatePolicy p s = |
|
|
|
let l = length $ filter (== letter p) s in |
|
|
|
let l = length $ filter (== letter p) s |
|
|
|
l >= lBound p && l <= uBound p |
|
|
|
in l >= lBound p && l <= uBound p |
|
|
|
|
|
|
|
|
|
|
|
validateLine :: Validator -> String -> Bool |
|
|
|
validateLine :: Validator -> String -> Bool |
|
|
|
validateLine v s = |
|
|
|
validateLine v s = |
|
|
|
case P.parse parserPolicy (T.pack s) of |
|
|
|
case P.parse parserPolicy (T.pack s) of |
|
|
|
P.Fail {} -> error "day2 - parser error" |
|
|
|
P.Fail {} -> error "day2 - parser error" |
|
|
|
P.Partial _ -> error "day2 - input error" |
|
|
|
P.Partial _ -> error "day2 - input error" |
|
|
|
P.Done i r -> v r (T.unpack i) |
|
|
|
P.Done i r -> v r (T.unpack i) |
|
|
|
|
|
|
|
|
|
|
|
xor :: Bool -> Bool -> Bool |
|
|
|
xor :: Bool -> Bool -> Bool |
|
|
|
xor True = not |
|
|
|
xor True = not |
|
|
@ -44,16 +48,15 @@ xor False = id |
|
|
|
|
|
|
|
|
|
|
|
validateCorrectPolicy :: Validator |
|
|
|
validateCorrectPolicy :: Validator |
|
|
|
validateCorrectPolicy p s = |
|
|
|
validateCorrectPolicy p s = |
|
|
|
let index1 = lBound p - 1 |
|
|
|
let index1 = lBound p - 1 |
|
|
|
index2 = uBound p - 1 |
|
|
|
index2 = uBound p - 1 |
|
|
|
indices = elemIndices (letter p) s in |
|
|
|
indices = elemIndices (letter p) s |
|
|
|
xor (index1 `elem` indices) (index2 `elem` indices) |
|
|
|
in xor (index1 `elem` indices) (index2 `elem` indices) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
day2 :: IO () |
|
|
|
day2 :: IO () |
|
|
|
day2 = do |
|
|
|
day2 = do |
|
|
|
rs <- lines <$> readFile "./input/day2" |
|
|
|
rs <- lines <$> readFile "./input/day2" |
|
|
|
putStr "[Day 2-1] # valid passwords: " |
|
|
|
putStr "[Day 2-1] # valid passwords: " |
|
|
|
print . length . filter (==True) . fmap (validateLine validatePolicy) $ rs |
|
|
|
print . length . filter (== True) . fmap (validateLine validatePolicy) $ rs |
|
|
|
putStr "[Day 2-2] # valid passwords: " |
|
|
|
putStr "[Day 2-2] # valid passwords: " |
|
|
|
print . length . filter (==True) . fmap (validateLine validateCorrectPolicy) $ rs |
|
|
|
print . length . filter (== True) . fmap (validateLine validateCorrectPolicy) $ rs |
|
|
|