AoC2018/Day14/Common.hs

34 lines
963 B
Haskell
Executable File

module Common where
import Data.Function (fix)
import Data.Word
import qualified Data.List as L
input :: Num a => a
input = 170641
scores :: () -> [Word8]
scores () = fix $ \ss ->
3 : 7 : concat (L.unfoldr (Just . step (quickLookup ss)) (0, 1, 2))
digits :: Num a => Int -> [a]
digits = map (\c -> fromIntegral (fromEnum c - fromEnum '0')) . show
step :: (Int -> Word8) -> (Int, Int, Int) -> ([Word8], (Int, Int, Int))
step ss (a, b, n) = (rs, (a', b', n'))
where
sa = fromIntegral (ss a)
sb = fromIntegral (ss b)
rs = digits (sa + sb)
n' = n + length rs
a' = (a + 1 + sa) `mod` n'
b' = (b + 1 + sb) `mod` n'
quickLookup :: [a] -> Int -> a
quickLookup xs = \n -> if n < 10 then xs !! n
else (nextLevel (n `div` 10)) !! (n `mod` 10)
where
nextLevel = quickLookup $ decimate $ L.tails xs
decimate [] = []
decimate xs = let (as, bs) = splitAt 10 xs in head as : decimate bs