Day 7 done. I now know more about Parsec
[advent-of-code-16.git] / advent05.hs
1 module Main(main) where
2
3 import Data.Hash.MD5 (md5s, Str(..))
4 import Data.List (isPrefixOf)
5 import qualified Data.Map.Lazy as Map
6
7 type Password = Map.Map Integer Char
8
9 input = "cxdnnyjw"
10
11 main :: IO ()
12 main = do
13 part1
14 part2
15
16
17 part1 :: IO ()
18 part1 = do
19 print $ take 8 [h!!5 | h <- filter (interesting) $ md5sequence input 0]
20
21 part2 :: IO ()
22 part2 = do
23 print $ Map.foldr (:) [] password
24 where interestingHashes =
25 [(read [h!!5], h!!6) |
26 h <- filter (interesting) (md5sequence input 0),
27 h!!5 `elem` "01234567"]
28 password = findPassword Map.empty interestingHashes
29
30
31 md5sequence :: String -> Integer -> [String]
32 md5sequence key i = (md5s (Str (key ++ show i))) : (md5sequence key (i+1))
33
34 interesting :: String -> Bool
35 interesting hash = "00000" `isPrefixOf` hash
36
37 dontReplace :: (Integer, Char) -> Password -> Password
38 dontReplace (k, v) = Map.insertWith (\_ v -> v) k v
39
40 findPassword :: Password -> [(Integer, Char)] -> Password
41 findPassword p (c:cs)
42 | Map.size p == 8 = p
43 | otherwise = findPassword p' cs
44 where p' = dontReplace c p