When we have a 2x2 square matrix we may have up to 24 different ones changing the positions of the elements.

We show some of them
```
a  b   a  b    a  c    a  c   a  d    a  d    b  a    b  a
c  d   d  c    d  b    b  d   b  c    c  b    c  d    d  c
```
You may think to generate the remaining ones until completing the set of 24 matrices.

Given a certain matrix of numbers, that may be repeated or not, calculate the total number of possible matrices that may be generated, changing the position of the elements.

E.g:
Case one
```
A = [[1,2,3],
     [3,4,5]]   #a 2x3 rectangle matrix with number 3 twice
```     
generates a set of ```360``` different matrices

Case two
```
A = [[1,1,1], 
     [2,2,3], 
     [3,3,3]]
```
generates a set of ```1260``` different matrices.

Case three
```
A = [[1,2,3],
     [4,5,6],
     [7,8,9]]
```     
generates a set of ```362880``` different matrices

This kata is not meant to apply a brute force algorithm to try to count the total amount of marices.

Features of The Random Tests
``` 
number of tests = 100
2 ≤ m ≤ 9
2 ≤ n ≤ 9
``` 
Enjoy it!

Available only in Python 2, Javascript and Ruby by the moment.

Difficulty: introductory

Starter code:

def count_perms(matrix):
	

Solutions:
from collections import Counter
from math import factorial

def count_perms(matrix):
    m, n = len(matrix), len(matrix[0])
    c = Counter([x for row in matrix for x in row])
    factors = []
    for x, count in c.most_common():
        if count > 1:
            factors.append(factorial(count))
    return factorial(m * n) / reduce(lambda a, b: a * b, factors, 1)

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

def count_perms(matrix):
    m = [elt for line in matrix for elt in line]
    return fact(len(m)) / reduce(lambda a,b: a*b, map(fact, Counter(m).values()), 1)

from collections import Counter
from itertools import chain, imap
from math import factorial
from operator import floordiv

def count_perms(matrix):
    xs = list(chain.from_iterable(matrix))
    return reduce(floordiv, imap(factorial, Counter(xs).itervalues()), factorial(len(xs)))

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

def count_perms(matrix):
    return factorial(len(matrix) * len(matrix[0])) // reduce(mul, map(factorial, Counter(sum(matrix, [])).values()))

from math import factorial as f
from functools import reduce
from collections import Counter
from operator import mul
def count_perms(m):
    m = sum(m,[])
    return f(len(m)) / reduce(mul,map(f,Counter(m).values()))

from collections import Counter
from itertools import chain
from operator import mul
from math import factorial

def count_perms(matrix):
    n = len(matrix) * len(matrix[0])
    c = Counter(chain.from_iterable(matrix))
    return factorial(n) / reduce(mul, map(factorial, c.itervalues()))

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

def count_perms(matrix):
    items = [a for b in matrix for a in b]
    return factorial(len(items)) // reduce(lambda x,y: x*y, list(map(factorial, list(Counter(items).values()))), 1)


import math

def count_perms(matrix):
    freq = dict()
    for sub_matrix in matrix:
        for elem in sub_matrix:
            if freq.get(elem) is not None:
                freq[elem] = freq[elem] + 1
            else:
                freq[elem] = 1
    denominator = 1
    for frequency in freq.values():
        denominator = denominator * math.factorial(frequency)
    return math.factorial(sum(freq.values())) / denominator

from math import factorial as f
from operator import mul

def count_perms(m):
    rep = [[i for s in m for i in s].count(j) for j in set([i for s in m for i in s])]
    rep = [f(i) for i in rep]
    tot = (len(m)*len(m[0]))
    return f(tot)/reduce(mul, rep, 1)

f,count_perms=lambda n:n<1or n*f(n-1),lambda m:(lambda l:reduce(lambda x,y:x/f(l.count(y)),set(l),f(len(l))))(sum(m,[]))