Символічна інтеграція многочленів


21

Застосуйте невизначений інтеграл до заданого рядка. Єдині правила, якими ви будете користуватися, визначені як такі:

∫cx ^ (n) dx = (c / (n + 1)) x ^ (n + 1) + C, n ≠ -1
c, C і n - всі постійні.

Технічні умови:

  • Ви повинні мати можливість інтегрувати поліноми з будь-якою з можливих особливостей:
    • Коефіцієнт, можливо, частка у форматі (numerator/denominator).
    • Визнання того, що e і π - константи, і при їх використанні вміти утворювати дроби або вирази, що містять їх (можна утримувати у дробі на зразок (e/denominator)або (numerator/e), або, якщо в експонентах x^(e+1))
      • Крім цих двох спеціальних констант, всі коефіцієнти будуть раціональними, реальними числами.
    • Експонент, можливо, частка, у форматі x^(exponent)
      • Вирази з ними eчи πв них, окрім самих себе, не будуть виражені. (вам не доведеться інтегрувати такі речі, як x^(e+1), але ви можете інтегруватися x^(e))
    • Може використовувати не-х 1-змінних змінних (тобто f)
      • Це лише для діапазонів 65-90 та 97-122 ASCII.
    • Вам не потрібно використовувати правила ланцюга або інтегрувати x^(-1).
  • Вихід повинен мати відступи (поділ між термінами, тобто x^2 + x + C.
  • Якщо невідомо, як інтегруватися з перерахованими вище функціями, програма повинна роздрукуватись "Cannot integrate "+input.
  • Це повинна бути повна програма.

Бонуси:

  • -10%, якщо ви надрукуєте "гарні" експоненти, відформатовані для розмітки (замість x^2, x<sup>2</sup>).
  • -10%, якщо ви роздрукуєте рівняння (тобто ∫xdx = (1/2)x^2 + C)

Приклади:

Вхід:

x

Вихід:

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

Вхід:

-f^(-2)

Вихід:

f^(-1) + C

Вхід:

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

Вихід:

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

Вхід:

πx^e

Вихід:

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

Вхід:

(f+1)^(-1)

Вихід:

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

1
Здивовані, у нас цього питання ще немає - але я не зміг знайти копію. +1
Цифрова травма

3
1. Я припускаю, що крім eта π, єдиними значеннями коефіцієнтів будуть раціональні числа? Тобто не потрібно обробляти багатовимірні многочлени? 2. Коли ви говорите " non-x 1-char змінних ", ви обмежуєтесь a-zA-Zчи маєте намір включити інші діапазони Unicode?
Пітер Тейлор

1
Як ви вважаєте, чи повинен бути бонус, якщо чиясь програма друкує ln(x) + Cна вклад x^(-1)?
Арктур

1
@Ampora Ні - це відкриває цілу банку глистів, що мають коефіцієнти ln.
Аддісон Кримп

1
@LeifWillerts 1) Я мав на увазі, що x^(e+1)це не буде інтеграндом, але це може бути результатом інтеграції. 2) Не буде багато змінних літер. 3) Так. 4) Так, але так і має бути (1/56)x^(1/7+1) + C(я помилився в прикладах).
Аддісон Кримп

Відповіді:


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

Це створює справжню функцію φ, яка приймає одну струну як вхідну. (Чи вважається це повною програмою для Mathematica?)

Необоротна версія буде такою:

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

Зауважте, що грецькі літери необхідні, щоб мати можливість використовувати всі інші букви у введенні.


7

MATLAB, 646 x 0,9 = 581,4 байт

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

Наразі це незавершене використання MATLAB, вбудованих у символічні можливості інтеграції. Наразі вимоги оновлено, тому формат тепер відповідає вимогам. Він також має право на другий бонус -10%.

Якщо хтось бажає викласти та запропонувати способи виправлення результатів, або використовувати цей код як основу для іншої відповіді, не соромтеся :). Якщо я зможу знайти час, я продовжую грати з ним і побачу, чи зможу я думати, як переформатувати результат.

Оновлення: Гаразд, тож після трохи більшої роботи, ось, яким кодом зараз виступає. Це все ще триває робота, але зараз наближається до відповідності необхідному результату.

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

Ось кілька прикладів того, що воно виробляє в даний час. Як бачите, це не зовсім правильно, але ближче.

Вхідні дані:

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

Виходи:

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

Я припускаю, що проблема з результатом, який у вас є, полягає в тому, що дроби не спрощують / переходять в єдиний коефіцієнт?
Аддісон Кримп

@FlagAsSpam, дроби спрощуються, але проблема полягає в тому, що вони опиняються на неправильній стороні змінної. Наприклад, у третьому прикладі, це призводить до того, x^(8/7)/8що, хоча математично правильно, немає в потрібній вам формі - (1/8)x^(8/7).
Том Карпентер

Враховуючи, що ви є єдиною на сьогодні відповіддю, я можу розглянути можливість змінити, якщо через день-два більше відповідей не надійде "будь-який математично правильний, дійсний вихід" для дробів.
Аддісон Кримп

Ваша відповідь справедлива - Вам більше не потрібно спрощувати дробовий вихід. c:
Addison Crump

Я трохи потім пограю в гольф і порахую байти.
Том Карпентер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.