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!

Source: codewars | Difficulty: EASY
Tags: String algorithms

Fundamentals

Data structures

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:
		if len(word) == n + m:
			letters = Counter(word)
			if sum((letters[c] for c in 'aeiou')) == n and all((c not in word for c in forbid_let)):
				result.append(word)
	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))]