-
Notifications
You must be signed in to change notification settings - Fork 0
/
2.hs
59 lines (47 loc) · 2.08 KB
/
2.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE BangPatterns #-}
import System.IO.Unsafe
import Control.Exception
import Data.Maybe
import Lib
dummyData = [ "1-3 a: abcde"
, "1-3 b: cdefg"
, "2-9 c: ccccccccc" ]
main = do
contents <- readFile "2.input"
print $ length $ filter isJust $ map (parsePassword toPassword') $ dummyData
print $ length $ filter isJust $ map (parsePassword toPassword') $ lines contents
newtype Password = Password String deriving Show
data PasswordSpec = PasswordSpec
{ from :: !Int
, to :: !Int
, chr :: !Char }
deriving Show
toSpec :: String -> Maybe PasswordSpec
toSpec str = let parts = str `splitOn` " "
(from:to:_) = (parts!!0) `splitOn` "-"
parsed = unsafePerformIO $ try @SomeException $ return
(PasswordSpec
(read @Int from)
(read @Int to)
(head (parts!!1))
)
in case parsed of
Left (ex) -> Nothing
Right spec -> Just spec
type PassFunc = String -> PasswordSpec -> Maybe Password
toPassword :: PassFunc
toPassword str spec = let chars = filter (==(chr spec)) str
in if length chars >= (from spec)
&& length chars <= (to spec)
then Just $ Password str
else Nothing
toPassword' :: PassFunc
toPassword' str spec = let chars = [str!!(from spec -1), str!!(to spec -1)]
in if (length $ filter (==chr spec) chars ) == 1
then Just $ Password str
else Nothing
parsePassword :: PassFunc -> String -> Maybe Password
parsePassword passFunc str = let (strSpec:strPass:_) = str `splitOn` ": "
spec = toSpec strSpec
in (passFunc strPass) =<< spec