{-# Language QuasiQuotes, BlockArguments #-}
module Main where
import Advent (format)
import Control.Monad (guard)
import Data.List (isInfixOf, tails)
main :: IO ()
IO ()
main =
do xs <- [format|2016 7 ((%a*)&(]|[)%n)*|]
print (length (filter supportsTLS xs))
print (length (filter supportsSSL xs))
split :: [String] -> ([String], [String])
split :: [[Char]] -> ([[Char]], [[Char]])
split [] = ([],[])
split [[Char]
x] = ([[Char]
x],[])
split ([Char]
x:[Char]
y:[[Char]]
z) =
case [[Char]] -> ([[Char]], [[Char]])
split [[Char]]
z of
([[Char]]
a,[[Char]]
b) -> ([Char]
x[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:[[Char]]
a,[Char]
y[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:[[Char]]
b)
supportsTLS :: [String] -> Bool
supportsTLS :: [[Char]] -> Bool
supportsTLS [[Char]]
xs =
case [[Char]] -> ([[Char]], [[Char]])
split [[Char]]
xs of
([[Char]]
supers, [[Char]]
hypers) -> ([Char] -> Bool) -> [[Char]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any [Char] -> Bool
forall {a}. Eq a => [a] -> Bool
hasABBA [[Char]]
supers Bool -> Bool -> Bool
&& Bool -> Bool
not (([Char] -> Bool) -> [[Char]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any [Char] -> Bool
forall {a}. Eq a => [a] -> Bool
hasABBA [[Char]]
hypers)
where
hasABBA :: [a] -> Bool
hasABBA [a]
ys = ([a] -> Bool) -> [[a]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any [a] -> Bool
forall {a}. Eq a => [a] -> Bool
isABBA ([a] -> [[a]]
forall a. [a] -> [[a]]
tails [a]
ys)
isABBA :: [a] -> Bool
isABBA (a
w:a
x:a
y:a
z:[a]
_) = a
w a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
z Bool -> Bool -> Bool
&& a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y Bool -> Bool -> Bool
&& a
w a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
x
isABBA [a]
_ = Bool
False
supportsSSL :: [String] -> Bool
supportsSSL :: [[Char]] -> Bool
supportsSSL [[Char]]
xs =
case [[Char]] -> ([[Char]], [[Char]])
split [[Char]]
xs of
([[Char]]
supers, [[Char]]
hypers) ->
Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
do s <- [[Char]]
supers
x:y:z:_ <- tails s
guard (x == z && x /= y)
h <- hypers
guard ( [y,x,y] `isInfixOf` h )