From 3fef2ec4e8e9981203b1df48f986999217774fc0 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Wed, 14 Dec 2016 19:39:55 +0000 Subject: [PATCH] Done day 14 --- README.html | 5 +++-- README.md | 3 ++- advent14.hs | 43 +++++++++++++++++++++++++++++++++++++++++++ advent14c.hs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 advent14.hs create mode 100644 advent14c.hs diff --git a/README.html b/README.html index 7bffdaa..1ece8ec 100644 --- a/README.html +++ b/README.html @@ -17,9 +17,10 @@

I'm using the basic Haskell Platform installation (install with

$ sudo aptitude install haskell-platform

).

-

I'm also using the MissingH and Parsec-number libraries (install with

+

I'm also using some extra libraries (install with

$ cabal install MissingH
-$ cabal install parsec-number
+$ cabal install parsec-number +$ cabal install cryptonite

)

Compile the code with

ghc --make advent01.hs
diff --git a/README.md b/README.md index 9fa5769..a4e1d71 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,11 @@ $ sudo aptitude install haskell-platform ``` ). -I'm also using the `MissingH` and `Parsec-number` libraries (install with +I'm also using some extra libraries (install with ``` $ cabal install MissingH $ cabal install parsec-number +$ cabal install cryptonite ``` ) diff --git a/advent14.hs b/advent14.hs new file mode 100644 index 0000000..f48dc6f --- /dev/null +++ b/advent14.hs @@ -0,0 +1,43 @@ +import Data.List (nub, tails, null) +import Data.Hash.MD5 (md5s, Str(..)) + +salt = "yjdafjpo" +-- salt = "abc" + +main :: IO () +main = do + part1 + part2 + +part1 :: IO () +part1 = print $ head $ drop 63 $ filter (\i -> possibleStart sq i && confirmStart sq i) [0..] + where sq = md5sequence + +part2 :: IO () +part2 = print $ head $ drop 63 $ filter (\i -> possibleStart sq i && confirmStart sq i) [0..] + where sq = md5sequenceS + +md5sequence :: [String] +md5sequence = [makeMd5 i | i <- [0..]] + where makeMd5 i = md5s (Str (salt ++ show i)) + +md5sequenceS :: [String] +md5sequenceS = [makeMd5 i | i <- [0..]] + where makeMd5 i = stretch $ md5s (Str (salt ++ show i)) + stretch h0 = foldr (\_ h -> md5s (Str h)) h0 [1..2016] + +possibleStart :: [String] -> Int-> Bool +-- possibleStart s i = not $ null $ repeats 3 $ s!!i +possibleStart s = not . null . repeats 3 . ((!!) s) + +confirmStart :: [String] -> Int -> Bool +confirmStart s i = any (confirmation) $ take 1000 $ drop (i+1) s + where c = head $ repeats 3 $ s!!i + confirmation m = c `elem` (repeats 5 m) + +repeats :: Int -> String -> [String] +repeats n = filter (null . tail) . map (nub) . substrings n + +substrings :: Int -> [a] -> [[a]] +substrings l = filter (\s -> (length s) == l) . map (take l) . tails + diff --git a/advent14c.hs b/advent14c.hs new file mode 100644 index 0000000..8f1eb6b --- /dev/null +++ b/advent14c.hs @@ -0,0 +1,52 @@ +import Data.List (nub, tails, null) +import Data.Hash.MD5 (md5s, Str(..)) + +import Data.ByteString.Char8 (pack) +import Crypto.Hash (hash, Digest, MD5) + +salt = "yjdafjpo" +-- salt = "abc" + +main :: IO () +main = do + part1 + part2 + + +part1 :: IO () +part1 = print $ head $ drop 63 $ filter (\i -> possibleStart sq i && confirmStart sq i) [0..] + where sq = md5sequence + +part2 :: IO () +part2 = print $ head $ drop 63 $ filter (\i -> possibleStart sq i && confirmStart sq i) [0..] + where sq = md5sequenceS + + +getHash :: String -> String +getHash bs = show (hash $ pack bs :: Digest MD5) + +md5sequence :: [String] +md5sequence = [makeMd5 i | i <- [0..]] + where makeMd5 i = getHash (salt ++ show i) + +md5sequenceS :: [String] +md5sequenceS = [makeMd5 i | i <- [0..]] + where makeMd5 i = stretch $ md5s (Str (salt ++ show i)) + stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016] + +possibleStart :: [String] -> Int-> Bool +-- possibleStart s i = not $ null $ repeats 3 $ s!!i +possibleStart s = not . null . repeats 3 . ((!!) s) + +confirmStart :: [String] -> Int -> Bool +confirmStart s i = any (confirmation) $ take 1000 $ drop (i+1) s + where c = head $ repeats 3 $ s!!i + confirmation m = c `elem` (repeats 5 m) + + +repeats :: Int -> String -> [String] +repeats n = filter (null . tail) . map (nub) . substrings n + +substrings :: Int -> [a] -> [[a]] +substrings l = filter (\s -> (length s) == l) . map (take l) . tails + -- 2.34.1