The principal of a school likes to put challenges to the students related with finding words of certain features.
One day she said: "Dear students, the challenge for today is to find a word that has only one vowel and seven consonants but cannot have the letters "y" and "m". I'll give a special award for the first student that finds it." One of the students used his dictionary and spent all the night without sleeping, trying in vain to find the word. The next day, the word had not been found yet.
This student observed that the principal has a pattern in the features for the wanted words: 

- The word should have **n** vowels, may be repeated, for example: in "engineering", n = 5.

- The word should have **m** consonants, may be repeated also: in "engineering", m = 6.

- The word should not have some forbidden letters (in an array), forbid_letters

You will be provided with a list of words, WORD_LIST(python/crystal), wordList(javascript), wordList (haskell), $word_list(ruby), and you have to create the function, ```wanted_words()```, that receives the three arguments in the order given above, ```wanted_words(n, m, forbid_list)```and output an array with the word or an array, having the words in the order given in the pre-loaded list, in the case of two or more words were found.

Let's see some cases:

```python
wanted_words(1, 7, ["m", "y"]) == ["strength"]
wanted_words(3, 7, ["m", "y"]) == ['afterwards', 'background', 'photograph', 'successful', 'understand']
```

For cases where no words are found the function will output an empty array.

```python
wanted_words(3, 7, ["a", "s" , "m", "y"]) == []
```

Help our student to win this and the next challenges of the school. He needs to sure about a suspect that he has. That many times there are no solutions for what the principal is asking for.
All words have its letters in lowercase format.
Enjoy it!

Difficulty: introductory

Starter code:

def wanted_words(n, m, forbid_let):
	

Solutions:
def wanted_words(vowels, consonants, forbidden):
    return [w for w in WORD_LIST
            if len(w) == vowels + consonants
                and sum(map(w.count, 'aeiou')) == vowels
                    and not any(c in w for c in forbidden)]

from collections import defaultdict
WORD_INDEX = defaultdict(list)
for w in WORD_LIST:
    WORD_INDEX[len(w), sum(map(w.count, 'aeiou'))].append(w)

def wanted_words(vowels, consonants, forbidden):
  return [w for w in WORD_INDEX[vowels + consonants, vowels] if not any(c in w for c in forbidden)]


def wanted_words(n, m, forbid_let):
    result = []
    for word in WORD_LIST:
        if set(forbid_let) & set(word):
            continue
        vowels = sum(1 for c in word if c in "aeiou")
        if vowels == n and len(word) == m + n:
            result.append(word)
    return result


from itertools import groupby

def _breakdown(word):
    v = sum(c in 'aeiou' for c in word)
    return v, len(word) - v
    
_WORDS = {k: list(group) for k, group in groupby(sorted(WORD_LIST, key=_breakdown), key=_breakdown)}

def wanted_words(v, c, forbidden):
    permitted = lambda word: not any(letter in word for letter in forbidden)
    return filter(permitted, _WORDS.get((v,c), []))

def wanted_words(n, m, forbid_let):
    f = set(forbid_let)
    return [word for word in WORD_LIST if len(word) == n + m and sum(c in 'aeiou' for c in word) == n and f.isdisjoint(word)]

from collections import Counter 

def wanted_words(n, m, forbid_let):
    result = []
    
    for word in WORD_LIST:                                        # for each word in word list
        if len(word) == n + m:                                    # if word length is correct
            letters = Counter(word)                               # create a count of letters
            
            if ( sum(letters[c] for c in "aeiou") == n            # if vowel count is correct
                and all(c not in word for c in forbid_let) ):     # and has no forbidden letters
                result.append(word)                               # add to the results
    
    return result

from collections import defaultdict
from itertools import filterfalse

is_vowel = set("aeiou").__contains__
result = defaultdict(lambda:defaultdict(list))
for w in WORD_LIST:
    nb_v = sum(map(is_vowel, w))
    nb_c = len(w) - nb_v
    result[nb_v][nb_c].append(w)

def wanted_words(n, m, forbid_let):
    return list(filterfalse(set(forbid_let).intersection, result.get(n, {}).get(m, [])))

def wanted_words(n, m, forbid_let):
    import re
    vov = "[aeiou]"
    cons= "[qwrtpysdfghjklzxcvbnm]"
    fb = "[" + ''.join(forbid_let) + "]"
    return [word for word in WORD_LIST if len(re.findall(vov, word))==n and len(re.findall(cons, word))==m and len(re.findall(fb, word))==0]

wanted_words = lambda n, m, f: [i for i in WORD_LIST if len([j for j in i if j in 'aeiou'])==n and len([j for j in i if not j in 'aeiou'])==m
    and not any(k in i for k in f)]

D = {w:(len([c for c in w if c in 'aeiou']), len([c for c in w if c not in 'aeiou'])) for w in WORD_LIST}

def wanted_words(n, m, forbid_let):
    return [w for w in WORD_LIST if D[w] == (n, m) and not [c for c in forbid_let if c in w]]

import re

def wanted_words(n, m, forbid_let):
    return [word for word in WORD_LIST if len(word) == n + m and len(re.findall("[aeiou]", word)) == n and not re.findall("[" + "".join(forbid_let) + "]", word)]