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)