- import re 
-   
- def fuzzy_filter(patterns, names): 
-     def match(pattern, words_index=0, pattern_index=0, word_index=0): 
-         return pattern_index == len(pattern) or ( 
-             words_index < len(words) and word_index < len(words[words_index]) 
-         ) and ( 
-             pattern[pattern_index] == words[words_index][word_index] and ( 
-                 match(pattern, words_index, pattern_index + 1, word_index + 1) or 
-                 match(pattern, words_index + 1, pattern_index + 1) 
-             ) or match(pattern, words_index + 1) 
-         ) 
-   
-     for name in names: 
-         words = list(map(str.lower, re.split(r'[\W_]+|(?<=\w)(?=[A-Z])', name))) 
-         if all(map(match, patterns.split())): 
-             yield name 
-   
- file_names = [ 
-     'HelloWorld.csv', 
-     'hello_windsor.pdf', 
-     'some_file_i_need.jpg', 
-     'san_francisco.png', 
-     'Another.file.txt', 
-     'A file name.rar' 
- ] 
-   
- queries = '''\ 
- hw 
- hwor 
- winds 
- sf 
- file need 
- sfr 
- file 
- file another 
- fnrar'''.splitlines() 
-   
- for query in queries: 
-     print(f'{query} -> {", ".join(fuzzy_filter(query, file_names))}') 
				aW1wb3J0IHJlCgpkZWYgZnV6enlfZmlsdGVyKHBhdHRlcm5zLCBuYW1lcyk6CiAgICBkZWYgbWF0Y2gocGF0dGVybiwgd29yZHNfaW5kZXg9MCwgcGF0dGVybl9pbmRleD0wLCB3b3JkX2luZGV4PTApOgogICAgICAgIHJldHVybiBwYXR0ZXJuX2luZGV4ID09IGxlbihwYXR0ZXJuKSBvciAoCiAgICAgICAgICAgIHdvcmRzX2luZGV4IDwgbGVuKHdvcmRzKSBhbmQgd29yZF9pbmRleCA8IGxlbih3b3Jkc1t3b3Jkc19pbmRleF0pCiAgICAgICAgKSBhbmQgKAogICAgICAgICAgICBwYXR0ZXJuW3BhdHRlcm5faW5kZXhdID09IHdvcmRzW3dvcmRzX2luZGV4XVt3b3JkX2luZGV4XSBhbmQgKAogICAgICAgICAgICAgICAgbWF0Y2gocGF0dGVybiwgd29yZHNfaW5kZXgsIHBhdHRlcm5faW5kZXggKyAxLCB3b3JkX2luZGV4ICsgMSkgb3IKICAgICAgICAgICAgICAgIG1hdGNoKHBhdHRlcm4sIHdvcmRzX2luZGV4ICsgMSwgcGF0dGVybl9pbmRleCArIDEpCiAgICAgICAgICAgICkgb3IgbWF0Y2gocGF0dGVybiwgd29yZHNfaW5kZXggKyAxKQogICAgICAgICkKCiAgICBmb3IgbmFtZSBpbiBuYW1lczoKICAgICAgICB3b3JkcyA9IGxpc3QobWFwKHN0ci5sb3dlciwgcmUuc3BsaXQocidbXFdfXSt8KD88PVx3KSg/PVtBLVpdKScsIG5hbWUpKSkKICAgICAgICBpZiBhbGwobWFwKG1hdGNoLCBwYXR0ZXJucy5zcGxpdCgpKSk6CiAgICAgICAgICAgIHlpZWxkIG5hbWUKCmZpbGVfbmFtZXMgPSBbCiAgICAnSGVsbG9Xb3JsZC5jc3YnLAogICAgJ2hlbGxvX3dpbmRzb3IucGRmJywKICAgICdzb21lX2ZpbGVfaV9uZWVkLmpwZycsCiAgICAnc2FuX2ZyYW5jaXNjby5wbmcnLAogICAgJ0Fub3RoZXIuZmlsZS50eHQnLAogICAgJ0EgZmlsZSBuYW1lLnJhcicKXQoKcXVlcmllcyA9ICcnJ1wKaHcKaHdvcgp3aW5kcwpzZgpmaWxlIG5lZWQKc2ZyCmZpbGUKZmlsZSBhbm90aGVyCmZucmFyJycnLnNwbGl0bGluZXMoKQoKZm9yIHF1ZXJ5IGluIHF1ZXJpZXM6CiAgICBwcmludChmJ3txdWVyeX0gLT4geyIsICIuam9pbihmdXp6eV9maWx0ZXIocXVlcnksIGZpbGVfbmFtZXMpKX0nKQ==