Table of contents
We will be solving a 6kyu problem from CodeWars. This one ->Count the smiley faces! | Codewars
The Question
Given an array (arr) as an argument complete the function countSmileys
that should return the total number of smiling faces.
Rules for a smiling face:
Each smiley face must contain a valid pair of eyes. Eyes can be marked as
:
or;
A smiley face can have a nose but it does not have to. Valid characters for a nose are
-
or~
Every smiling face must have a smiling mouth that should be marked with either
)
orD
No additional characters are allowed except for those mentioned.
Valid smiley face examples::) :D ;-D :~)
Invalid smiley faces:;( :> :} :]
Example
countSmileys([':)', ';(', ';}', ':-D']); // should return 2;
countSmileys([';D', ':-(', ':-)', ';~)']); // should return 3;
countSmileys([';]', ':[', ';*', ':$', ';-D']); // should return 1;
Note
In case of an empty array return 0. You will not be tested with invalid input (input will always be an array). The order of the face (eyes, nose, mouth) elements will always be the same.
Let's Solve it
We can use Regular Expressions (regex) to quickly and efficiently solve the given problem. To begin, let's import the re library at the beginning of the count_smileys() function. Our next step is to define a regex pattern of all the valid smileys.
The pattern is r"[:;][-~]?[)D]"
Here's a breakdown of the pattern.
[:;] : encasing :
and ;
with an []
means that we will match the pattern if any one of those two comes up. Since both are valid for the eyes.
[-~]? : Since the nose is optional, we will add a ?
mark beside the brackets to signify that the nose is optional and the pattern will match whether the smiley has a nose or not.
[)D] : Finally we will end by writing the mouth.
In the count_smileys function, we will create a variable called count to keep the count of the smileys. We can add a For loop to loop over the items given in the array and use re.search
to match the patterns.
Here's the Final result
import re
def count_smileys(arr):
count = 0
smileys = r"[:;][-~]?[)D]"
for item in arr:
if re.search(smileys, item):
count += 1
return count