Done day 14
authorNeil Smith <neil.git@njae.me.uk>
Wed, 14 Dec 2016 19:39:55 +0000 (19:39 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Wed, 14 Dec 2016 19:39:55 +0000 (19:39 +0000)
README.html
README.md
advent14.hs [new file with mode: 0644]
advent14c.hs [new file with mode: 0644]

index 7bffdaa8d1e090570dc1fd0cebb1d75d9d42f768..1ece8ec72e6c9e5f3d7e30456c23e11d35d05f03 100644 (file)
 <p>I'm using the basic Haskell Platform installation (install with</p>
 <pre><code>$ sudo aptitude install haskell-platform</code></pre>
 <p>).</p>
-<p>I'm also using the <code>MissingH</code> and <code>Parsec-number</code> libraries (install with</p>
+<p>I'm also using some extra libraries (install with</p>
 <pre><code>$ cabal install MissingH
-$ cabal install parsec-number</code></pre>
+$ cabal install parsec-number
+$ cabal install cryptonite</code></pre>
 <p>)</p>
 <p>Compile the code with</p>
 <pre><code>ghc --make advent01.hs</code></pre>
index 9fa57694a2f05e1ef846ed9f8f365a003b09484c..a4e1d71cbfeebd5a53a84a186e9f79c7e0ea12b6 100644 (file)
--- 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 (file)
index 0000000..f48dc6f
--- /dev/null
@@ -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 (file)
index 0000000..8f1eb6b
--- /dev/null
@@ -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
+