DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 9: Encoding Error

Collapse
 
bgaster profile image
Benedict Gaster

Ah, this one lead to a nice relaxing day :-) Nothing fancy in my Haskell implementation, but fine all the same. Relies heavely on lazyness to avoid over production, but if the feature exists why not use it...

-- helper function to generate tuple perms of a list and pass to a function
perms :: Eq t => (t -> t -> a) -> [t] -> [a]
perms f xs = [f x y | (x:ys) <- tails (nub xs), y <- ys]

-- asserts if a number is XMAS encrypted correctly
valid :: [Int] -> Int -> Int -> (Bool,Int)
valid is l i = let ps = map (\(_,_,z) -> z) $ perms (\x y -> (x,y,x+y)) (take l is)
                   n  = is !! i
               in (n `elem` ps, n)

-- checks, for a given header length, that each input is valid 
check :: Int -> [Int] -> [(Bool, Int)]
check l is | length is <= l+1 = []
           | otherwise      =  valid is l l : check l (tail is)

-- find the first input that is not valid with respec to XMAS encryption 
task1 :: Int -> [Int] -> Int
task1 l = snd . head . filter (not . fst) . check l

-- find the a contiguous sequence whose sum is equal to the input (calulated by task1) and
-- sum the smallest and largest number in that sequence
task2 :: Int -> [Int] -> Int
task2 n = (\xs -> head xs + last xs) . snd . head . filter ((n==) . fst) . map (\xs -> (sum xs, sort xs)) 
                        . filter ((>1) . length) . (:) [] . filter (not . null) . concatMap tails . inits

main = do xs <- readFile "day9_input" <&> lines <&> fmap (read :: String -> Int)
          let x = task1 25 xs
          print x
          print (task2 x xs)
Enter fullscreen mode Exit fullscreen mode