Expanding powers of expressions of the form ax+b I solved the following problem:


  Write a function expand that takes in an expression with a single, one character variable, and expands it. The expression is in the form (ax+b)^n where a and b are integers which may be positive or negative, x is any one-character long variable, and n is a natural number. If a = 1, no coefficient will be placed in front of the variable. If a = -1, a "-" will be placed in front of the variable.
  The expanded form should be returned as a string in the form ax^b+cx^d+ex^f... where a, c, and e are the coefficients of the term, x is the original one character variable that was passed in the original expression and b, d, and f, are the powers that x is being raised to in each term and are in decreasing order. If the coefficient of a term is zero, the term should not be included. If the coefficient of a term is one, the coefficient should not be included. If the coefficient of a term is -1, only the "-" should be included. If the power of the term is 0, only the coefficient should be included. If the power of the term is 1, the caret and power should be excluded.


Examples:

expand("(p-1)^3");      // returns "p^3-3p^2+3p-1"
expand("(2f+4)^6");     // returns "64f^6+768f^5+3840f^4+10240f^3+15360f^2+12288f+4096"
expand("(-2a-4)^0");    // returns "1"
expand("(-12t+43)^2");  // returns "144t^2-1032t+1849"
expand("(r+0)^203");    // returns "r^203"
expand("(-x-1)^2");     // returns "x^2+2x+1"


My solution passed all tests but I would like to know how it can be improved.

function expand(str) {
    const fac = n =&gt; n &lt; 2 ? 1 : n * fac(n - 1);
    let result = '', [_, a, x, b, n] = str.match(/\((-?\d*)([a-z])([-+]\d+)\)\^(\d+)/);

    a = a ? a == '-' ? -1 : parseInt(a) : 1;
    b = parseInt(b); n = parseInt(n);

    for (let i = n; i &gt;= 0; i--) {
        let k = n - i;
        let c = !b &amp;&amp; k &gt; 0
            ? 0
            : a**i * b**k * (k == 0
                ? 1
                : fac(n) / (fac(k) * fac(n - k)));

        if (Math.abs(c) == 1 &amp;&amp; i &gt; 0) c = c &gt; 0 ? '+' : '-';
        else c = c &gt; 0 ? `+${c}` : c;
        if (c) result += c;

        if (i &gt; 0 &amp;&amp; c) result += x;
        if (i &gt; 1 &amp;&amp; c) result += `^${i}`;
    }

    return result[0] == '+' ? result.substr(1) : result;
}


I got this problem from a coding challenges site. https://www.codewars.com/kata/binomial-expansion All the context that i had to solve it came from the description of the task.

I did not try to obfuscate the code. As Roland Illig stated, most of the single-letter variables come from the task. Variables a, x, b, n come from the parts of the input expression of the form (ax+b)^n. Variable k comes from a math formula n!/(k!(n-k)!) for the binomial coefficient. Variable c is the coefficient of the term being formed, and its mentioned in ax^b+cx^d+ex^f. So names come from problem's domain.

I mostly just do coding challenges for fun, and I like to golf things a bit. I concede the code lacks readability though.

My main concern is that small numbers like 203 have large factorials and produce overflow. One of the test cases is expand("(r+0)^203");    // returns "r^203". I did not wanted to treat this case separately. Hence I used conditions !b &amp;&amp; k &gt; 0 and k == 0 to avoid calculating factorials for "large" n when b == 0. I would like to change this with a better approach for calculating the binomial coefficients. Sadly I don't know enough math.

If someone solves this problem differently I would love to see their code.

I don't have too much experience writing questions in stackexchange and English is not my native language. Tried to format the text to the best of my ability. Thanks all for your patience.
You don't need the special case for k == 0. When k == 0, the result of the other expression will be 1 as well.

For this sequence of binomial coefficients you don't need to calculate the full fak expression each time. You can also start with c = a ** i, and then, for each k, multiply by (n - k) / (k + 1) * b / a. That's a bit faster and provides less risk of producing numeric overflows, which would result in slightly incorrect coefficients. The Wikipedia article on binomial coefficients should explain this in more detail.