def multinomial_coefficients0(m, n, _tuple=tuple, _zip=zip):
    """Return a dictionary containing pairs ``{(k1,k2,..,km) : C_kn}``
    where ``C_kn`` are multinomial coefficients such that
    ``n=k1+k2+..+km``.

    For example:

    >>> from sympy import multinomial_coefficients
    >>> multinomial_coefficients(2, 5) # indirect doctest
    {(0, 5): 1, (1, 4): 5, (2, 3): 10, (3, 2): 10, (4, 1): 5, (5, 0): 1}

    The algorithm is based on the following result:

       Consider a polynomial and its ``n``-th exponent::

         P(x) = sum_{i=0}^m p_i x^i
         P(x)^n = sum_{k=0}^{m n} a(n,k) x^k

       The coefficients ``a(n,k)`` can be computed using the
       J.C.P. Miller Pure Recurrence [see D.E.Knuth, Seminumerical
       Algorithms, The art of Computer Programming v.2, Addison
       Wesley, Reading, 1981;]::

         a(n,k) = 1/(k p_0) sum_{i=1}^m p_i ((n+1)i-k) a(n,k-i),

       where ``a(n,0) = p_0^n``.
    """

    if not m:
        if n:
            return {}
        return {(): 1}
    if m == 2:
        return binomial_coefficients(n)
    symbols = [(0,)*i + (1,) + (0,)*(m - i - 1) for i in range(m)]
    s0 = symbols[0]
    p0 = [_tuple(aa - bb for aa, bb in _zip(s, s0)) for s in symbols]
    r = {_tuple(aa*n for aa in s0): 1}
    l = [0] * (n*(m - 1) + 1)
    l[0] = r.items()
    for k in range(1, n*(m - 1) + 1):
        d = defaultdict(int)
        for i in range(1, min(m, k + 1)):
            nn = (n + 1)*i - k
            if not nn:
                continue
            t = p0[i]
            for t2, c2 in l[k - i]:
                tt = _tuple([aa + bb for aa, bb in _zip(t2, t)])
                d[tt] += nn*c2
                if not d[tt]:
                    del d[tt]
        r1 = [(t, c//k) for (t, c) in d.items()]
        l[k] = r1
        r.update(r1)
    return r
dataset/ETHPy150Open sympy/sympy/sympy/ntheory/multinomial.py/multinomial_coefficients0/original