-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDay14.hs
53 lines (40 loc) · 1.3 KB
/
Day14.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
module Main where
import MD5
import Utilities
import Data.List
import Data.Maybe
hash1 :: String -> String
hash1 = md5s
hashes :: String -> (String -> String) -> [(Int, String)]
hashes salt hash = [(n, hash (salt ++ show n)) | n <- [0..]]
-- elements that are repeated at least n times
repetitions :: Eq a => Int -> [a] -> [a]
repetitions n xs = [head g | g <- group xs, length g >= n]
-- first element (if any) that occurs 3 times consecutively in the list
firstTriplet :: Eq a => [a] -> Maybe a
firstTriplet = listToMaybe . repetitions 3
keys :: [(Int, String)] -> [(Int, String)]
keys hs = [(n, s) |
(n, s):rest <- tails hs,
c <- maybeToList (firstTriplet s),
any ((replicate 5 c `isInfixOf`) . snd) (take 1000 rest)]
solve1 :: String -> Int
solve1 salt = fst (keys (hashes salt hash1)!!63)
tests1 :: [(String, Int)]
tests1 = [("abc", 22728)]
-- Part Two
hash2 :: String -> String
hash2 = times 2017 hash1
solve2 :: String -> Int
solve2 salt = fst (keys (hashes salt hash2)!!63)
tests2 :: [(String, Int)]
tests2 = [("abc", 22551)]
main :: IO ()
main = do
s <- readFile "input/14.txt"
let input = head (lines s)
putStr (unlines (failures "solve1" solve1 tests1))
print (solve1 input)
-- These are quite slow
putStr (unlines (failures "solve2" solve2 tests2))
print (solve2 input)