Retina, 53 43 42 41 40 35 bytes
^[^x]+ |(\^1)?\w(?=1*x.(1+)| |$)
$2
For counting purposes each line goes in a separate file, but you can run the above as a single file by invoking Retina with the -s
flag.
This expects the numbers in the input string to be given in unary and will yield output in the same format. E.g.
1 + 11x + -111x^11 + 11x^111 + -1x^11111
-->
11 + -111111x + 111111x^11 + -11111x^1111
instead of
1 + 2x + -3x^2 + 2x^3 + -1x^5
-->
2 + -6x + 6x^2 + -5x^4
Explanation
The code describes a single regex substitution, which is basically 4 substitutions compressed into one. Note that only one of the branches will fill group $2
so if any of the other three match, the match will simply be deleted from the string. So we can look at the four different cases separately:
^[^x]+<space>
<empty>
If it's possible to reach a space from the beginning of the string without encountering an x
that means the first term is the constant term and we delete it. Due to the greediness of +
, this will also match the plus and the second space after the constant term. If there is no constant term, this part will simply never match.
x(?= )
<empty>
This matches an x
which is followed by a space, i.e. the x
of the linear term (if it exists), and removes it. We can be sure that there's a space after it, because the degree of the polynomial is always at least 2.
1(?=1*x.(1+))
$1
This performs the multiplication of the coefficient by the exponent. This matches a single 1
in the coefficient and replaces it by the entire corresponding exponent via the lookahead.
(\^1)?1(?= |$)
<empty>
This reduces all remaining exponents by matching the trailing 1
(ensured by the lookahead). If it's possible to match ^11
(and a word boundary) we remove that instead, which takes care of displaying the linear term correctly.
For the compression, we notice that most of the conditions don't affect each other. (\^1)?
won't match if the lookahead in the third case is true, so we can put those two together as
(\^1)?1(?=1*x.(1+)| |$)
$2
Now we already have the lookahead needed for the second case and the others can never be true when matching x
, so we can simply generalise the 1
to a \w
:
(\^1)?\w(?=1*x.(1+)| |$)
$2
The first case doesn't really have anything in common with the others, so we keep it separate.