Given a string ``string`` that contains only letters, you have to find out the number of **unique** strings (including ``string`` itself) that can be produced by re-arranging the letters of the ``string``.  Strings are case **insensitive**.

HINT: Generating all the unique strings and calling length on that isn't a great solution for this problem. It can be done a lot faster...

## Examples

```python
uniqcount("AB") = 2      # "AB", "BA"
uniqcount("ABC") = 6     # "ABC", "ACB", "BAC", "BCA", "CAB", "CBA"
uniqcount("ABA") = 3     # "AAB", "ABA", "BAA"
uniqcount("ABBb") = 4    # "ABBB", "BABB", "BBAB", "BBBA"
uniqcount("AbcD") = 24   # "ABCD", etc.
```

Difficulty: introductory

Starter code:

def uniq_count(s):
	

Solutions:
from operator import mul
from functools import reduce
from collections import Counter
from math import factorial as fact

def uniq_count(s):
    return fact(len(s)) // reduce(mul, map(fact, Counter(s.lower()).values()), 1)

from collections import Counter
from functools import reduce
from math import factorial


def uniq_count(s):
    f = (factorial(c) for c in Counter(s.upper()).values())
    return factorial(len(s)) // reduce(int.__mul__, f, 1)

from functools import reduce, lru_cache
from collections import Counter
from math import factorial
from operator import mul

fact = lru_cache(maxsize=None)(factorial)

def uniq_count(s):
    return fact(len(s)) // reduce(mul, map(fact, Counter(s.upper()).values()), 1)

from collections import Counter
from functools import reduce
from math import factorial


def uniq_count(s):
    return factorial(len(s)) // reduce(lambda x,y: factorial(y) * x, list(Counter(s.lower()).values()), 1)


from math import factorial
from collections import Counter
from functools import reduce

def uniq_count(s):
    return factorial(len(s)) // reduce(lambda x, y: x * factorial(y) , Counter(s.lower()).values(), 1)

from collections import Counter
from functools import reduce
from math import factorial
from operator import mul

def uniq_count(string):
    return factorial(len(string)) // reduce(mul, map(factorial, Counter(string.lower()).values()), 1)

from math import factorial
from functools import reduce
from operator import mul
uniq_count=lambda a:factorial(len(a))//reduce(mul,[factorial(a.lower().count(i))for i in set(a.lower())],1)

from math import factorial

def uniq_count(s):
    s = s.lower()
    n = len(s)
    d = 1
    for c in set(s):
        d *= factorial(s.count(c))
    return factorial(n)//d