From 86e396d56cbd48529af2beab22da1a8f8e9d8fd9 Mon Sep 17 00:00:00 2001 From: Sloane Perrault Date: Wed, 21 Sep 2022 09:19:52 -0400 Subject: [PATCH] solve: day 2, part 2 --- 2020/02/part2.hs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 2020/02/part2.hs diff --git a/2020/02/part2.hs b/2020/02/part2.hs new file mode 100755 index 0000000..7ffbfc9 --- /dev/null +++ b/2020/02/part2.hs @@ -0,0 +1,45 @@ +#!/usr/bin/env runghc + +import Data.Char + +data PasswordEntry = PasswordEntry { pos1 :: Int, pos2 :: Int, char :: Char, password :: String } + deriving (Show) + +-- This could be a lot better... +instance Read PasswordEntry where + readsPrec _ input = + let (pos1', rest) = span isDigit input + pos1 = read pos1' :: Int + (_, rest') = splitAt 1 rest + (pos2', rest'') = span isDigit rest' + pos2 = read pos2' :: Int + (_:char:_:_:password) = rest'' + in + [(PasswordEntry pos1 pos2 char password, "")] + + +main = interact solve + +solve = show . length . filter (isValidPasswordEntry . readPasswordEntry) . lines + +readPasswordEntry :: String -> PasswordEntry +readPasswordEntry = read + +(!!?) :: [a] -> Int -> Maybe a +[] !!? _ = Nothing +(x:xs) !!? 0 = Just x +(_:xs) !!? idx = xs !!? (idx - 1) + +maybeToBool (Just a) = a +maybeToBool Nothing = False + +xor :: Bool -> Bool -> Bool +xor l r = l /= r + +isValidPasswordEntry (PasswordEntry pos1 pos2 char pass) = + (maybeToBool $ fmap (==char) char1) `xor` + (maybeToBool $ fmap (==char) char2) + where + char1 = pass !!? (pos1 - 1) + char2 = pass !!? (pos2 - 1) +