41 lines
1.2 KiB
Haskell
41 lines
1.2 KiB
Haskell
#!/usr/bin/env stack
|
|
-- stack --resolver lts-9.18 script
|
|
|
|
import Data.List
|
|
import Data.List.Split
|
|
import Data.Char
|
|
import Data.Bits
|
|
import Text.Printf
|
|
|
|
twist :: [Int] -> Int -> Int -> [Int]
|
|
twist xs len skip =
|
|
end ++ start
|
|
where (knot, keep) = splitAt len xs
|
|
(start, end) = splitAt skip $ keep ++ reverse knot
|
|
|
|
twists :: [Int] -> [Int] -> Int -> [Int]
|
|
twists list [] k = list
|
|
twists list (x:xs) k = twists (twist list x k) xs (k+1)
|
|
|
|
hashRound :: Int -> [Int] -> [Int]
|
|
hashRound n lens = drop rot list ++ take rot list
|
|
where list = foldl' (\acc (x,k) -> twist acc x k) [0..(n-1)] $ zip lens (cycle [0..(n-1)])
|
|
rot = n - (sum (zipWith (+) [0..] lens) `rem` n)
|
|
|
|
sparseHash :: [Int] -> [Int]
|
|
sparseHash lengths =
|
|
hashRound 256 . concat . replicate 64 $ lengths ++ [17, 31, 73, 47, 23]
|
|
|
|
denseHash :: [Int] -> [Int]
|
|
denseHash h = foldr xor 0 <$> chunksOf 16 h
|
|
|
|
grid :: String -> [[Int]]
|
|
grid input =
|
|
map (denseHash . sparseHash . map ord . ((input++"-")++) . show) [0..127]
|
|
|
|
main :: IO ()
|
|
main = do
|
|
let input = "stpzcrnm"
|
|
let g = grid input
|
|
mapM_ (putStrLn . concatMap (printf "%08b")) g
|
|
print . length . filter (=='1') . concat $ map (concatMap (printf "%08b")) g
|