1 import Data.List.Split (splitOn, chunksOf)
4 import Text.Printf (printf)
8 text <- readFile "data/advent10.txt"
9 let ls = map read $ splitOn "," text
15 part1 lengths = (tied!!0) * (tied!!1)
16 where (tied, _, _) = foldl step ([0..255], 0, 0) lengths
19 part2 :: String -> String
20 part2 text = densify tied
21 where lengths = p2lengths text
22 (tied, _, _) = foldl step ([0..255], 0, 0) lengths
24 step :: ([Int], Int, Int) -> Int -> ([Int], Int, Int)
25 step (original, start, skip) len = (replaced, start', skip + 1)
26 where replaced = tie original start len
27 start' = (start + len + skip) `mod` (length original)
29 tie :: [a] -> Int -> Int -> [a]
30 tie original start len = replace original replacement start
31 where replacement = reverse $ extract original start len
33 extract :: [a] -> Int -> Int -> [a]
34 extract items from len = take len $ drop from $ items ++ items
36 replace :: [a] -> [a] -> Int -> [a]
37 replace original replacement from = take (length original) (start ++ replacement ++ remainder)
38 where excess = drop (length original - from) replacement
39 stub = drop (length excess) original
40 start = take from (excess ++ stub)
41 remainder = drop (length $ start ++ replacement) original
44 p2lengths :: String -> [Int]
45 p2lengths text = take (length chunk * 64) $ cycle chunk
46 where chunk = map ord text ++ [17, 31, 73, 47, 23]
48 densify :: [Int] -> String
49 densify ns = concatMap (printf "%02x") codes
50 where chunks = chunksOf 16 ns
52 codes = map compress chunks