Символическая интеграция полиномов

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)
      • Это только для ASCII диапазонов 65-90 и 97-122.
    • Вам не нужно использовать правило цепочки или интегрировать 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. Когда вы говорите « переменные не x 1-char », вы ограничиваете a-zA-Zили намереваетесь включить другие диапазоны Unicode?
Питер Тейлор
1
Как вы думаете, должен ли быть бонус, если чья-то программа печатает ln(x) + Cдля ввода x^(-1)?
Арктур
1
@Ampora No - открывает целую банку червей, работающих с коэффициентами 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",
            σ
        ]
    ]
)&

Обратите внимание, что греческие буквы необходимы, чтобы иметь возможность использовать все остальные буквы во входных данных.

senegrom
источник
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:
Эддисон Крамп
Тогда я немного проиграю и посчитаю байты.
Том Карпентер