never executed always true always false
    1 {-|
    2 Module:      Y2015.D05
    3 Description: Advent of Code Day 05 Solutions.
    4 License:     MIT
    5 Maintainer:  @tylerjl
    6 
    7 Solutions to the day 05 set of problems for <adventofcode.com>.
    8 -}
    9 module Y2015.D05
   10   ( clean
   11   , isNice
   12   , isNicer
   13   , thriceVoweled
   14   , twiceRow
   15   ) where
   16 
   17 import Y2015.Util ((<&&>))
   18 
   19 import Data.List (group, isInfixOf)
   20 
   21 -- |Whether a given string is "nice" per the spec.
   22 isNicer
   23   :: String -- ^ Test input string
   24   -> Bool -- ^ Whether string is nice
   25 isNicer = repeatedPair <&&> repeatedBetween
   26 
   27 repeatedPair :: String -> Bool
   28 repeatedPair (x:y:zs)
   29   | [x, y] `isInfixOf` zs = True
   30   | otherwise = repeatedPair (y : zs)
   31 repeatedPair _ = False
   32 
   33 repeatedBetween :: String -> Bool
   34 repeatedBetween (x:y:z:zs)
   35   | x == z = True
   36   | otherwise = repeatedBetween (y : z : zs)
   37 repeatedBetween _ = False
   38 
   39 -- |Predicate to determine whether a given string is "nice".
   40 isNice
   41   :: String -- ^ Test input string.
   42   -> Bool -- ^ Whether the given input string is nice.
   43 isNice = clean <&&> thriceVoweled <&&> twiceRow
   44 
   45 -- |Predicate to determine whether a string eschews forbidden strings.
   46 clean
   47   :: String -- ^ Input string.
   48   -> Bool -- ^ Whether the string is clean.
   49 clean = not . flip any forbiddenStrings . flip isInfixOf
   50 
   51 forbiddenStrings :: [String]
   52 forbiddenStrings = ["ab", "cd", "pq", "xy"]
   53 
   54 -- |Predicate to determine whether a given string contains two letters
   55 -- |in a row.
   56 twiceRow
   57   :: String -- ^ Input string to test.
   58   -> Bool -- ^ Whether the given string passes the predicate.
   59 twiceRow = any ((> 1) . length) . group
   60 
   61 -- |Predicate to determine whether the given string contains at least three
   62 -- |vowels.
   63 thriceVoweled
   64   :: String -- ^ Input string to test.
   65   -> Bool -- ^ Whether the string passes the predicate.
   66 thriceVoweled = (> 2) . length . filter isVowel
   67 
   68 isVowel :: Char -> Bool
   69 isVowel = flip elem ("aeiou" :: String)