this repo has no description
1module Lib
2 ( processLengths
3 , sparseHash
4 , denseHash
5 ) where
6
7import Data.List.Grouping (splitEvery)
8import Data.Bits (xor)
9import Data.Char
10import Numeric (showHex)
11
12-- Part 1
13processLengths :: [Int] -> [Int]
14processLengths = go 0 0 [0..255]
15 where go :: Int -> Int -> [Int] -> [Int] -> [Int]
16 go _ _ rope [] = rope
17 go p skip rope (l:ls) =
18 go (mod (p + l + skip) 256) (skip + 1) (twistRope p l rope) ls
19
20-- Part 2
21sparseHash :: String -> [Int]
22sparseHash str = go 1 0 0 [0..255] lengths
23 where lengths = (map ord str) ++ [17,31,73,47,23]
24 go :: Int -> Int -> Int -> [Int] -> [Int] -> [Int]
25 go 64 _ _ rope [] = rope
26 go r p s rope [] = go (r + 1) p s rope lengths
27 go r p s rope (l:ls) =
28 go r (mod (p + l + s) 256) (s + 1) (twistRope p l rope) ls
29
30denseHash :: [Int] -> String
31denseHash ints = concatMap getHex nums
32 where nums :: [Int]
33 nums = map (\g -> foldl1 xor g) $ splitEvery 16 ints
34
35getHex :: Int -> String
36getHex i = let h = showHex i ""
37 in if length h == 2 then h else "0" ++ h
38
39twistRope :: Int -> Int -> [Int] -> [Int]
40twistRope p l rope =
41 let frontEnd = (p + l) - 256
42 newSection = reverse . take l . drop p $ cycle rope
43 in (drop (l - frontEnd) newSection) ++ (drop frontEnd . take p $ rope) ++
44 (take (l - frontEnd) newSection) ++ (drop (p + l) rope)