advent-of-code/2015/day11/day11.hs

42 lines
1.1 KiB
Haskell
Raw Normal View History

2024-12-03 08:15:40 +11:00
import Aoc
import Data.Char ( ord, chr )
import Data.List ( group, nub )
import Data.Bifunctor ( bimap )
toBase26' :: Char -> Int
toBase26' = (\n->n-97) . ord
fromBase26' :: Int -> Char
fromBase26' = chr . (97+)
toBase26 :: [Char] -> [Int]
toBase26 = reverse . map toBase26'
fromBase26 :: [Int] -> [Char]
fromBase26 = reverse . map fromBase26'
next :: [Int] -> [Int]
next (25:rest) = 0:next rest
next (x:rest)
| x `elem` [7,10,13] = x+2:rest -- skip i,o,l
| otherwise = x+1:rest
lengthy :: [a] -> Bool
lengthy = (>1) . length
getAnswer :: [[Int]] -> [Char]
getAnswer = fromBase26 . head
part1 :: String -> (String, [[Int]])
part1 = (\ps -> (getAnswer ps, tail ps)) . filter isSecure . iterate next . toBase26
where
hasStraight = any lengthy . filter ((==1) . head) . group . map (uncurry (-)) . adjacents
hasNoIOL = not . any (`elem` [8,14,11])
hasPair = lengthy . nub . map head . filter lengthy . group
isSecure ns = hasStraight ns && hasNoIOL ns && hasPair ns
part2 :: p -> [[Int]] -> String
part2 _ = getAnswer
main :: IO ()
main = aocMain' single part1 part2