From a96ab19024e787f87530c3a4b8d25c8373791454 Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Sat, 9 Dec 2017 23:00:44 -0800 Subject: [PATCH] Day 10 --- 10.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10.txt | 1 + 2 files changed, 55 insertions(+) create mode 100644 10.hs create mode 100644 10.txt diff --git a/10.hs b/10.hs new file mode 100644 index 0000000..06f1999 --- /dev/null +++ b/10.hs @@ -0,0 +1,54 @@ +import Data.List.Split (splitOn) +import Data.Sequence (Seq, update, fromList) +import qualified Data.Sequence as S (lookup) +import Data.Char (ord) +import Data.Bits (xor) +import Data.Foldable (toList) +import Numeric (showHex) + +type Ring = Seq Int +type Position = Int +type Skip = Int +type Length = Int +type State = (Ring, Position, Skip) + +(%) = mod + +unsafeLookup :: Int -> Seq Int -> Int +unsafeLookup index seq = + case S.lookup index seq of + Just i -> i + +twist :: State -> Length -> State +twist (ring, position, skip) len = + let end = position + len - 1 + positions = map (% 256) [position..end] + posRev = zip positions $ reverse positions + newRing = foldl (\currRing (pos, rev) -> update pos (unsafeLookup rev ring) currRing) ring posRev + in (newRing, (end + skip + 1) % 256, skip + 1) + +hash :: [Length] -> State -> State +hash lengths state = foldl twist state lengths + +condense :: [Int] -> [Int] +condense [] = [] +condense ns = + let block = foldr xor 0 $ take 16 ns + in block : (condense $ drop 16 ns) + +showHexPrepended :: Int -> (String -> String) +showHexPrepended n + | n < 15 = showHex 0 . showHex n + | otherwise = showHex n + +main :: IO () +main = do + input <- readFile "10.txt" + let lengths = map read $ splitOn "," input + newLengths = map ord input ++ [17, 31, 73, 47, 23] + (hashed, _, _) = hash lengths (fromList [0..255], 0, 0) + (sparseHash, _, _) = iterate (hash newLengths) (fromList [0..255], 0, 0) !! 64 + condensedHash = condense $ toList sparseHash + hexString = foldr (\digit str -> showHexPrepended digit $ str) "" condensedHash + print $ (unsafeLookup 0 hashed) * (unsafeLookup 1 hashed) + print $ hexString diff --git a/10.txt b/10.txt new file mode 100644 index 0000000..bb063bd --- /dev/null +++ b/10.txt @@ -0,0 +1 @@ +18,1,0,161,255,137,254,252,14,95,165,33,181,168,2,188 \ No newline at end of file