2017-12-10 19:00:11 +00:00
|
|
|
import Data.List.Split (splitOn, chunksOf)
|
2017-12-10 07:00:44 +00:00
|
|
|
import Data.Char (ord)
|
|
|
|
import Data.Bits (xor)
|
2017-12-10 19:00:11 +00:00
|
|
|
import Text.Printf (printf)
|
2017-12-10 07:00:44 +00:00
|
|
|
|
|
|
|
type Length = Int
|
2017-12-10 19:00:11 +00:00
|
|
|
type State = ([Int], Int, Int)
|
2017-12-10 07:00:44 +00:00
|
|
|
(%) = mod
|
|
|
|
|
|
|
|
twist :: State -> Length -> State
|
|
|
|
twist (ring, position, skip) len =
|
2017-12-10 19:00:11 +00:00
|
|
|
let rotated = slice position 256 $ cycle ring
|
|
|
|
twisted = (reverse $ take len rotated) ++ drop len rotated
|
|
|
|
newRing = slice (256 - position) 256 $ cycle twisted
|
|
|
|
in (newRing, (position + len + skip) % 256, skip + 1)
|
|
|
|
where slice start amount = take amount . drop start
|
|
|
|
|
2017-12-10 07:00:44 +00:00
|
|
|
hash :: [Length] -> State -> State
|
|
|
|
hash lengths state = foldl twist state lengths
|
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
input <- readFile "10.txt"
|
|
|
|
let lengths = map read $ splitOn "," input
|
|
|
|
newLengths = map ord input ++ [17, 31, 73, 47, 23]
|
2017-12-10 19:00:11 +00:00
|
|
|
(hashed, _, _) = hash lengths ([0..255], 0, 0)
|
|
|
|
(sparseHash, _, _) = iterate (hash newLengths) ([0..255], 0, 0) !! 64
|
|
|
|
hexString = concat . map (printf "%02x" . foldr xor 0) . chunksOf 16 $ sparseHash :: String
|
|
|
|
print $ hashed !! 0 * hashed !! 1
|
|
|
|
print $ hexString
|