Symboliczna integracja wielomianów


21

Zastosuj całkę nieoznaczoną do danego ciągu. Jedyne reguły, których będziesz używać, są zdefiniowane jako takie:

∫cx ^ (n) dx = (c / (n + 1)) x ^ (n + 1) + C, n ≠ -1
c, C i n są stałymi.

Dane techniczne:

  • Musisz być w stanie zintegrować wielomiany z dowolną z możliwych funkcji:
    • Współczynnik, być może ułamek formatu (numerator/denominator).
    • Rozpoznanie, że e i π są stałymi, a przy ich użyciu mogą być w stanie tworzyć ułamki lub wyrażenia je zawierające (mogą być przechowywane w ułamkach takich jak (e/denominator)lub (numerator/e), lub w wykładnikach x^(e+1))
      • Oprócz tych dwóch specjalnych stałych wszystkie współczynniki będą liczbami wymiernymi, rzeczywistymi.
    • Wykładnik, być może ułamek, w formacie x^(exponent)
      • Wyrażenia z elub πw nich, poza sobą, nie będą w wykładnikach. (nie będziesz musiał integrować takich rzeczy x^(e+1), ale możesz się zintegrować x^(e))
    • Może używać zmiennych innych niż x 1-char (tj. f)
      • Dotyczy to tylko zakresów ASCII 65–90 i 97–122.
    • Nie musisz używać reguły łańcuchowej ani integracji x^(-1).
  • Dane wyjściowe muszą mieć wypełnienie (separacja między terminami, tj x^2 + x + C.
  • Jeśli nie wiadomo, jak zintegrować się z powyższymi funkcjami, program powinien wydrukować "Cannot integrate "+input.
  • To musi być pełny program.

Bonusy:

  • -10%, jeśli wydrukujesz „ładne” wykładniki sformatowane dla markdown (zamiast x^2, x<sup>2</sup>).
  • -10%, jeśli wydrukujesz równanie (tj. ∫xdx = (1/2)x^2 + C)

Przykłady:

Wkład:

x

Wydajność:

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

Wkład:

-f^(-2)

Wydajność:

f^(-1) + C

Wkład:

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

Wydajność:

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

Wkład:

πx^e

Wydajność:

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

Wkład:

(f+1)^(-1)

Wydajność:

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

1
Zaskoczeni, że nie mamy tego pytania - ale nie mogłem znaleźć dupka. +1
Cyfrowy uraz

3
1. Zakładam, że oprócz ei πjedynymi wartościami współczynników będą liczby wymierne? Czyli nie jest konieczne obsługiwanie wielomianów wielowymiarowych? 2. Kiedy mówisz „ zmienne inne niż x 1-char ”, czy ograniczasz się, a-zA-Zczy zamierzasz uwzględnić inne zakresy Unicode?
Peter Taylor,

1
Czy uważasz, że powinna istnieć premia, jeśli czyjś program drukuje ln(x) + Cdane wejściowe x^(-1)?
Arcturus,

1
@Ampora Nie - to otwiera całą puszkę robaków zajmujących się współczynnikami ln.
Addison Crump,

1
@LeifWillerts 1) Miałem na myśli, że x^(e+1)nie będzie to integrand, ale może być wynikiem integracji. 2) Nie będzie wielu zmiennych literowych. 3) Tak. 4) Tak, ale powinno być (1/56)x^(1/7+1) + C(popełniłem błąd w przykładach).
Addison Crump

Odpowiedzi:


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",σ]])&

To tworzy prawdziwą funkcję φ, która przyjmuje jeden ciąg jako dane wejściowe. (Czy to się liczy jako kompletny program dla Mathematica?)

Wersja bez golfa to:

φ=(
    σ="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",
            σ
        ]
    ]
)&

Zauważ, że greckie litery są niezbędne, aby móc używać wszystkich pozostałych liter na wejściu.


7

MATLAB, 646 x 0,9 = 581,4 bajtów

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

Jest to obecnie praca w toku z wykorzystaniem MATLAB-ów wbudowanych w funkcje symbolicznej integracji. Obecnie wymagania zostały zaktualizowane, więc format jest teraz zgodny z wymaganiami. To także kwalifikuje się do drugiego bonusu -10%.

Jeśli ktoś chce zgłosić i zasugerować sposoby korekty danych wyjściowych lub użyć tego kodu jako podstawy do kolejnej odpowiedzi, nie krępuj się :). Jeśli znajdę czas, będę się z nim bawił i sprawdzę, czy uda mi się sformatować wyjście.

Aktualizacja: Ok, więc po trochę więcej pracy, oto jak obecnie wygląda kod. Nadal jest w toku, ale teraz jest coraz bliżej dopasowania wymaganej wydajności.

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

Oto kilka przykładów tego, co obecnie produkuje. Jak widać, nie jest to w porządku, ale coraz bliżej.

Wejścia:

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

Wyjścia:

∫(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)

Zakładam, że problem z wyjściem, który masz, polega na tym, że ułamki nie upraszczają / nie przechodzą w pojedynczy współczynnik?
Addison Crump,

@FlagAsSpam, ułamki są uproszczone, ale problem polega na tym, że kończą po niewłaściwej stronie zmiennej. Na przykład w trzecim przykładzie powoduje, że x^(8/7)/8choć poprawne matematycznie nie jest w takiej formie, w jakiej chcesz - (1/8)x^(8/7).
Tom Carpenter,

Biorąc pod uwagę, że jesteś jedyną odpowiedzią do tej pory, mogę rozważyć zmianę tego, że jeśli w ciągu jednego lub dwóch nie dojdzie już więcej odpowiedzi na „matematycznie poprawne, prawidłowe dane wyjściowe” dla ułamków.
Addison Crump,

Twoja odpowiedź jest prawidłowa - Nie musisz już upraszczać ułamkowego wyniku. c:
Addison Crump,

Potem trochę golfa i policzę bajty.
Tom Carpenter
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.