Symbolic Integration of Polynomials

21

3

Apply an indefinite integral to a given string. The only rules you will be using are defined as such:

∫cx^(n)dx = (c/(n+1))x^(n+1) + C, n ≠ -1
c, C, and n are all constants.

Specifications:

  • You must be able to integrate polynomials with any of the possible features:
    • A coefficient, possibly a fraction in the format (numerator/denominator).
    • Recognition that e and π are constants, and in their use, be able to form fractions or expressions containing them (can be held in a fraction like (e/denominator) or (numerator/e), or, if in exponents, x^(e+1))
      • Aside of these two special constants, all coefficients will be rational, real numbers.
    • An exponent, possibly a fraction, in the format x^(exponent)
      • Expressions with e or π in them, aside of themselves, will not be in exponents. (you will not have to integrate stuff like x^(e+1), but you might integrate x^(e))
    • Can use non-x 1-char variables (i.e. f)
      • This is only for ASCII ranges 65-90 and 97-122.
    • You do not have to use chain rule or integrate x^(-1).
  • Output must have padding (separation between terms, i.e. x^2 + x + C.
  • If it is unknown how to integrate with the above features, the program should print out "Cannot integrate "+input.
  • It must be a full program.

Bonuses:

  • -10% if you print out the "pretty" exponents formatted for markdown (instead of x^2, x<sup>2</sup>).
  • -10% if you print out the equation (i.e. ∫xdx = (1/2)x^2 + C)

Examples:

Input:

x

Output:

(1/2)x^(2) + C

Input:

-f^(-2)

Output:

f^(-1) + C

Input:

(1/7)x^(1/7) + 5

Output:

(1/56)x^(8/7) + 5x + C

Input:

πx^e

Output:

(π/(e+1))x^(e+1) + C

Input:

(f+1)^(-1)

Output:

Cannot integrate (f+1)^(-1)

Addison Crump

Posted 2015-12-15T21:28:43.833

Reputation: 10 763

1Surprised we don't already have this question - but I couldn't find a dup. +1 – Digital Trauma – 2015-12-15T21:34:24.680

@DigitalTrauma There is this, though.

– Addison Crump – 2015-12-15T21:35:06.527

3>

  • I presume that other than e and π, the only values in coefficients will be rational numbers? I.e. it's not necessary to handle multivariable polynomials? 2. When you say "non-x 1-char variables", are you restricting to a-zA-Z or do you intend to include other Unicode ranges?
  • < – Peter Taylor – 2015-12-15T21:36:00.833

    Dang, I was going to post this at some point. Oh well. – Arcturus – 2015-12-15T21:37:23.547

    1Do you think there should be a bonus if someone's program prints ln(x) + C for an input of x^(-1)? – Arcturus – 2015-12-15T21:38:25.197

    1@Ampora No - that opens up a whole can of worms dealing with coefficients of ln. – Addison Crump – 2015-12-15T21:39:01.483

    Do you really need to print a 27-char string Cannot integrate polynomial? – xnor – 2015-12-15T21:39:55.447

    @xnor Cannot integrate, and yes. – Addison Crump – 2015-12-15T21:40:30.670

    What would πe integrate as? Would e be considered as exp(1), or as a variable? If the former, would we assume x to be the variable? – Tom Carpenter – 2015-12-20T03:21:28.813

    @TomCarpenter πe would integrate as a constant, so it would integrate to (πe)x. I wouldn't make a coefficient this complicated, so you may assume that this will be an untested input. – Addison Crump – 2015-12-20T14:51:04.087

    How are we supposed to solve the halting problem? – FUZxxl – 2015-12-23T14:18:47.517

    @FlagAsSpam I misread your question. For the general case, computing integrals involves solving the halting problem since e^(ax^2) is integrable if and only if a is always 0, but being able to show that is equal to the halting problem. – FUZxxl – 2015-12-23T14:46:04.787

    So it is necessary for it to only solve the polynomial integrals? Are built-ins allowed? – TanMath – 2015-12-25T21:47:53.377

    @TanMath Yes and yes, but make sure you do output "Cannot integrate " for things that are more difficult than just power rule. – Addison Crump – 2015-12-26T00:45:12.133

    a few questions for clarification: x^(e+1) is given as an example of how transcendentals may appear in an exponent, but also as an example of how they won't. -> !? Also, could there ever be multiple letter variables, if so how to choose which to integrate over? May we use pi or p for π? Lastly, is the output supposed to be concise, and if so how is that defined? f.x. is (1/7)x^(1/7) to (1/8)x^(1/7+1) + C ok? – Leif Willerts – 2016-02-02T13:12:31.280

    1@LeifWillerts 1) I meant that x^(e+1) will not be an integrand, but it may be the result of an integration. 2) There will not be multiple letter variables. 3) Yes. 4) Yes, but it should be (1/56)x^(1/7+1) + C (I made a mistake in the examples). – Addison Crump – 2016-02-02T13:31:58.503

    Now that I can comment: I assumed that C is also not going to be an input variable but reserved for the integration constant. Otherwise, of course, this would need to be clarified and the code changed accordingly. – senegrom – 2016-02-06T17:24:33.190

    @senegrom Yes, that's correct. c: Nice answer, btw. – Addison Crump – 2016-02-06T17:32:29.657

    Answers

    2

    Mathematica 478 * 0.9 = 430.2

    φ=(α=ToExpression;Π=StringReplace;σ="Cannot integrate "<>#1;Λ=DeleteDuplicates@StringCases[#1,RegularExpression["[a-df-zA-Z]+"]];μ=Length@Λ;If[μ>1,σ,If[μ<1,Λ="x",Λ=Λ[[1]]];Ψ=α@Π[#1,{"e"->" E ","π"->" π "}];Φ=α@Λ;Θ=α@Π[#1,{"e"->" 2 ","π"->" 2 "}];λ=Exponent[Θ,Φ,List];Θ=Simplify[Θ*Φ^Max@@Abs@λ];Θ=PowerExpand[Θ/.Φ->Φ^LCM@@Denominator@λ];If[Coefficient[Ψ,Φ,-1]==0&&PolynomialQ[Θ,Φ],"∫("<>#1<>")d"<>Λ<>" = "<>Π[ToString[Integrate[Ψ,Φ],InputForm],{"E"->"e","Pi"->"π"}]<>" + C",σ]])&
    

    This creates a true function φ that takes one String as Input. (Does that count as complete program for Mathematica?)

    The ungolfed version would be:

    φ=(
        σ="Cannot integrate "<>#1;
        Λ=DeleteDuplicates@StringCases[#1,RegularExpression["[a-df-zA-Z]+"]];
        If[Length@Λ>1,σ,
            If[Length@Λ<1,Λ="x",Λ=Λ[[1]]];
            Ψ=ToExpression@StringReplace[#1,{"e"->" E ","π"->" π "}];
            Φ=ToExpression@Λ;
            Θ=ToExpression@StringReplace[#1,{"e"->" 2 ","π"->" 2 "}];
            λ=Exponent[Θ,Φ,List];
            Θ=Simplify[Θ*Φ^Max@@Abs@λ];
            Θ=PowerExpand[Θ/.Φ->Φ^LCM@@Denominator@λ];
            If[Coefficient[Ψ,Φ,-1]==0&&PolynomialQ[Θ,Φ],
                "∫("<>#1<>")d"<>Λ<>" = "<>StringReplace[ToString[Integrate[Ψ,Φ],InputForm],{"E"->"e","Pi"->"π"}]<>" + C",
                σ
            ]
        ]
    )&
    

    Note that the Greek letters are necessary to be able to use all the other letters in the input.

    senegrom

    Posted 2015-12-15T21:28:43.833

    Reputation: 423

    7

    MATLAB, 646 x 0.9 = 581.4 bytes

    t=input('','s');p=char(960);s=regexprep(t,{p,'pi([a-zA-Z])','([a-zA-Z])pi','([\)e\d])([a-zA-Z])','([a-zA-Z])(([\(\d]|pi))','e^(\(.+?\))','e'},{'pi','pi*$1','$1*pi','$1*$2','$1*$2','exp($1)','exp(1)'});r=[s(regexp(s,'\<[a-zA-Z]\>')),'x'];r=r(1);e=0;try
    I=int(sym(strsplit(s,' + ')),r);S=[];for i=I
    S=[S char(i) ' + '];end
    b=0;o=[];for i=1:nnz(S)
    c=S(i);b=b+(c==40)-(c==41);if(c==42&&S(i+1)==r)||(b&&c==32)
    c='';end
    o=[o c];end
    o=regexprep(char([8747 40 t ')d' r ' = ' o 67]),{'pi','exp\(1\)','exp','\^([^\(])',['1/' r]},{p,'e','e^','^($1)',[r '^(-1)']});catch
    e=1;end
    if e||~isempty(strfind(o,'log'))
    disp(['Cannot integrate ' t]);else
    disp(o);end
    

    This is currently a work-in-progress using MATLABs built in symbolic integration capabilities. Currently the requirements have been updated so the format now matches the requirements. It also does qualify for the second -10% bonus.

    If anyone wants to pitch in and suggest ways of correcting the output, or use this code as a basis for another answer, feel free :). If I can find the time, I'll keep playing with it and see if I can think how to reformat the output.

    Update: Ok, so after a bit more work, here is how the code currently stands. It is still a work in progress, but now getting closer to matching the required output.

    t=input('','s'); %Get input as a string
    p=char(960); %Pi character
    s=regexprep(t,{p,'pi([a-zA-Z])','([a-zA-Z])pi','([\)e\d])([a-zA-Z])','([a-zA-Z])(([\(\d]|pi))','e^(\(.+?\))','e'},{'pi','pi*$1','$1*pi','$1*$2','$1*$2','exp($1)','exp(1)'}); %Reformat input to work with built in symbolic integration
    r=[s(regexp(s,'\<[a-zA-Z]\>')),'x'];r=r(1); %determine the variable we are integrating
    e=0; %Assume success
    try
        I=int(sym(strsplit(s,' + ')),r); %Integrate each term seperately to avoid unwanted simplificaiton
        S=[];
        for i=I
            S=[S char(i) ' + ']; %Recombine integrated terms
        end
        %Now postprocess the output to try and match the requirements
        b=0;o=[];
        for i=1:nnz(S)
            %Work through the integrated string character by character
            c=S(i);
            b=b+(c=='(')-(c==')'); %Keep track of how many layers deep of brackets we are in
            if(c=='*'&&S(i+1)==r)||(b&&c==' ') %If a '*' sign preceeds a variable. Also deblank string.
                c=''; %Delete this character
            end
            o=[o c]; %merge into new output string.
        end
        o=regexprep([char(8747) '(' t ')d' r ' = ' o 'C'],{'pi','exp\(1\)','exp','\^([^\(])',['1/' r]},{p,'e','e^','^($1)',[r '^(-1)']});
    catch
        e=1; %failed to integrate
    end
    if e||~isempty(strfind(o,'log'))
        disp(['Cannot integrate ' t])  %bit of a hack - matlab can integrate 1/x, so if we get a log, we pretend it didn't work.
    else
        disp(o)% Display it.
    end
    

    Here are some examples of what it currently produces. As you can see, it's not quite right, but getting closer.

    Inputs:

    x
    -f^(-2)
    (1/7)x^(1/7) + 5
    πx^e
    (f+1)^(-1)
    

    Outputs:

    ∫(x)dx = x^(2)/2 + C
    ∫(-f^(-2))df = f^(-1) + C
    ∫((1/7)x^(1/7) + 5)dx = x^(8/7)/8 + 5x + C
    ∫(πx^(e))dx = (πx^(e+1))/(e+1) + C
    Cannot integrate (f+1)^(-1)
    

    Tom Carpenter

    Posted 2015-12-15T21:28:43.833

    Reputation: 3 990

    I assume the problem with output that you're having is that the fractions don't simplify/go into a single coefficient? – Addison Crump – 2015-12-20T18:13:14.333

    @FlagAsSpam, the fractions are simplifying, but the trouble is they end up on the wrong side of the variable. For instance in the third example it results in x^(8/7)/8 which while mathematically correct is not in the form you want it - (1/8)x^(8/7). – Tom Carpenter – 2015-12-20T18:27:10.910

    Considering that you are the only answer so far, I might consider changing that if no more answers come through in a day or two to "any mathematically correct, valid output" for fractions. – Addison Crump – 2015-12-20T18:46:57.853

    Your answer is valid - You do not have to simplify fractional output anymore. c: – Addison Crump – 2015-12-21T21:46:26.087

    I will golf it down a bit then and count the bytes. – Tom Carpenter – 2015-12-22T06:23:55.693

    Can you use ||nnz() instead of ~isempty(). Also, I think you can use|instead of||, sincee` is a scalar... – Stewie Griffin – 2018-04-17T09:00:59.543