Оценить строку полиномиального выражения


18

Создайте функцию, которая принимает полиномиальное уравнение, значение xи возвращает результат операции.

Пример: дано 4x^2+2x-5и x=3вывод 37. Это результат4(3)^2+2(3)-5

  • Предположим, что все полиномы верны
  • Полиномиальный формат всегда будет coefficient(variable)^exponent => 4x^2за исключением:
    • Когда показатель 1это будетcoefficient(variable) => 4x
    • Когда коэффициент 1будет(variable)^exponent => x^2
  • Полиномы только одна переменная
  • Использование внешних библиотек запрещено
  • Коэффициент и переменная ввода могут быть положительными и отрицательными числами.

Контрольные примеры

  • ("3x^3-5x^2+2x-10", 5) => 250
  • ("10x^4-5x^3-10x^2+3x+50", 3) => 644
  • ("10x+20", 10) => 120
  • ("-20x^2+20x-50", -8) => -1490
  • ("9", 5) => 9
  • ("8x^2+5", 0) => 5

Обновить

  • Полиномиальный формат всегда будет coefficient(variable)^exponent => 4x^2за исключением:
    • Когда показатель 1это будетcoefficient(variable) => 4x
    • Когда коэффициент 1будет(variable)^exponent => x^2
  • Убрано правило отрицательного показателя. Моя ошибка. Действительный полином не содержит отрицательного показателя
  • Показатель 0будет простоcoefficient
  • Добавлен контрольный пример для input 0

Это , поэтому выигрывает самый короткий ответ в байтах.


3
Насколько гибок формат ввода? Вместо того, чтобы 3x^3-5x^2+2x-10мы могли ввести 3*x^3-5*x^2+2*x-10? Или [3 -5 2 -10]. [3 2 1 0]?
Луис Мендо


4
Что такое «внешняя библиотека» и насколько она справедлива по сравнению с языками, в которых «eval» уже реализован как функция?
Оливье Грегуар

1
Мои извинения Я не использую свой компьютер со вчерашнего дня. Я обновил вызов с предложениями, которые вы мне дали. Пожалуйста, посмотрите на него и откройте снова, если все в порядке.
Луис Фелипе Де Иисус Муньос

Ответы:


12

JavaScript (ES7), 48 байт

Основано на предложении @RickHitchcock

Ожидается Xв верхнем регистре. Принимает ввод в синтаксисе карри (p)(X).

p=>X=>eval(p.replace(/[X^]/g,c=>c<{}?'*X':'**'))

Попробуйте онлайн!


JavaScript (ES7), 49 байт

Тот же подход, что и у @DeadPossum . Принимает ввод в синтаксисе карри (p)(x).

p=>x=>eval(p.split`x`.join`*x`.split`^`.join`**`)

Попробуйте онлайн!


1
Я думаю, что вы можете сохранить пару байтов, используя replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Рик Хичкок

@RickHitchcock Я не могу использовать ссылку, fесли она не включена в число байтов, за счет 2 байтов, которые должны быть сохранены. Мне нравится этот метод, хотя. Там может быть способ сохранить один или два байта, обновив его как-то.
Арно

2
@RickHitchcock Если мы можем взять Xв верхнем регистре, то мы можем сделать a<{}?'*X':'**', сохраняя байт. Отсюда мой вопрос к ОП.
Арно

1
не могу справиться xодин
l4m2

1
@ l4m2 Правила соревнований были обновлены. : / Раньше было 1xдля x.
Арно


8

Python 3 , 53 50 48 байтов

редактировать : -5 байт благодаря Денису!

lambda p,x:eval(p.translate({94:"**",120:"*x"}))

Попробуйте онлайн!

Используется, translateчтобы избежать цепочки replaceвызовов; Версия Python 3 translateменее неудобна, чем его предшественница.


"*(%d)"%xможет стать "*(x)".
Деннис

Спасибо, я так и не понял, что это xбыло в моей evalсфере! Я обновлю.
etene

1
На самом деле, поскольку xбольше не является строковым представлением, "*x"работает также.
Деннис

Даже лучше ! Еще раз спасибо.
etene

5

R , 44 байта

function(f,x)eval(parse(t=gsub("x","*x",f)))

Попробуйте онлайн!

Довольно просто с R. Замените nxна, n*xа затем evalна parseстроку d. xиспользуется так, как мы называем второй аргумент.

Функция Eval даже может быть использована более непосредственно с правильно отформатированным первым аргументом, и другие формальные аргументы ( y, zи т.д.) могут быть легко добавлены:

R , 20 байт (не конкурирует)

function(f,x)eval(f)

Попробуйте онлайн!




3

JavaScript (Node.js) , 113 108 байт

_=>x=>_.match(/-?(?:[x\d]+|\^?)+/g).reduce((a,b)=>b.split`x`[0]*(~b.indexOf`x`?x**(b.split`^`[1]||1):1)+a,0)

Попробуйте онлайн!

Благодаря @Arnauld


Поскольку лучшее JS-решение на сегодняшний день от @Arnauld (49 байт) уже опубликовано и использует его eval, я решил использовать Regex и уменьшить вместо этого.

Довольно долго по сравнению с его, хотя.

Пояснение:

A =>                            // lambda function accepting argument 1 
    x =>                        // argument number 2 (currying syntax used)
        A.match(                // this matches all instance of what comes next 
                                // and converts to array
       /[-]?(?:[x\d]+|\^?)+/g)  // regexp for -ve sign , variable number and ^ sign 
            .reduce((a, b) =>   // reduce the array to single (take 2 params a,b)
                b.split `x`     // split b at instances of `x` 
                        [0]     // and select the first instance 
                * (b.indexOf`x` // multiply that by value of index of x in b 
                    > 0 ?       // if it is greater than 0 then 
                x **            // multiplication will be with x raised to power
               (l = b.split `^` // set variable split b at every `x` 
                   [1]||1       // choose first index otherwise set to one
                )               // this is what x is raised to the power 
                : 1)            // in the case x is not present multiply by 1
                + a,            //  add value of `a` to that value 
        0)                      // in case no reduce is possible set value to 0


В настоящее время это не удается в последнем тестовом примере (должно быть 0,25). Вы можете сохранить несколько байтов, используя -вместо [-], ~b.indexOf`x` вместо b.indexOf`x`>0и удаляя, l=который не используется. (Но это не исправляет ошибку.)
Арно

@Arnauld: Спасибо. Не знаю, почему это так, увидим, в чем проблема
Мухаммед Салман

Ну, проблема в том, что ваше регулярное выражение распадается 1x^-2на -.
Арно

3

05AB1E , 16 19 байтов

„*(I')J'xs:'^„**:.E

+3 байта как исправление для отрицательного ввода x.

.E( Запуск от имени пакетного кода ) был заменен на Запуск от имени Pythoneval в этом последнем коммите @Adnan , но эта версия еще не на TIO. @ Mr.Xcoder проверил его на своем локальном (последняя версия) 05AB1E, чтобы убедиться, что он работает.
Смотрите эту версию, не .Eвидя, как она преобразует строку выражения.

Объяснение:

„*I')J'xs:    # Replace all "x" with "*(n)" (where `n` is the input-integer)
              #  i.e. 5 and 3x^3-5x^2+2x-10 → 3*(5)^3-5*(5)^2-2*(5)-10
'^„**:        # Replace all "^" with "**"
              #  i.e. 3*(5)^3-5*(5)^2-2*(5)-10 → 3*(5)**3-5*(5)**2-2*(5)-10
.E            # Evaluate as Python-eval
              #  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → 250

Альтернатива 25- байтовой программе, работающей на текущей версии TIO:

„*(I')J'xs:'^„**:“…¢(“s')J.e

Попробуйте онлайн.

Объяснение:

„*(I')J'xs:'^„**:    # Same as explained above
“…¢(“                # Literal string "print("
     s               # Swap both
      ')             # Literal character ")"
        J            # Join everything together
                     #  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → print(3*(5)**3-5*(5)**2-2*(5)-10)
.e                   # Run as Python code
                     #  i.e. print(3*(5)**3-5*(5)**2-2*(5)-10) → 250

“…¢(“это строка print(, потому что:

  • и начинает и заканчивает сжатую строку
  • …¢равно, 0426потому что он смотрит на индексы в файле info.txt , где имеет индекс 4 и ¢имеет индекс 26.
  • Этот индекс 0426затем используется в файле словаря , где строка 427 (индекс 426) - это слово, которое оно выбирает, что printв данном случае.
  • Он (не имеет индекса в файле info.txt, поэтому интерпретируется как есть.

2

JavaScript (Node.js) , 143 байта

Я знаю, что есть лучшие ответы, но я хотел сделать это, не используя eval

(_,x)=>_.match(/[+-]?(?:[a-z0-9.]+|\^-?)+/gi).reduce((a,b)=>~~(b.split('x')[0])*(b.indexOf('x')>0?Math.pow(x,(l=(b.split('^')[1]))?l:1):1)+a,0)

Попробуйте онлайн!


Ваше регулярное выражение не нуждается, [a-z0-9.]не так ли? Единственное письмо , которое может появиться в x. Любой почему .? Вам не нужно обрабатывать нецелые коэффициенты или показатели.
Питер Кордес



2

Java 8, 150 149 148 байт

n->s->new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s.replace("x","*"+n).replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))

Не уверен, возможно ли иметь карри лямбда-функцию, которая выдает исключение. Если это так, можно сохранить 1 байт, изменив (s,n)->на n->s->. -1 байт, спасибо @ OlivierGrégoire за то, что показали мне, как это сделать.

Попробуйте онлайн.

Объяснение:

n->s->     // Method with integer and String parameters and Object return-type
  new javax.script.ScriptEngineManager().getEngineByName("JS")
            //  Use a JavaScript engine
   .eval(s  //  And eval the input
      .replace("x","*"+n)
            //   After all 'x' has been replaced with '*n'
            //   (where `n` is the input-integer)
      .replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))
            //   And all `A^B` have have been replaced with `Math.pow(A,B)`
            //   (where both `A` and `B` are integers)

К сожалению, JavaScript eval не поддерживает **, поэтому я должен использовать вместо него более длинную замену Math.pow..


JavaScript поддерживает **(ES7 +), почему это не поддерживается?
Мухаммед Салман

Также нет eval в Java. Это не может быть правильно?
Мухаммед Салман

@ MuhammadSalman Нет, у Java нет eval. И я думаю, что этот встроенный JavaScript-eval, с которым я могу использовать ScriptEngineManager, не обновлялся в Java JDK в течение многих лет, поэтому он не поддерживает ES7+..
Кевин Круйссен

Чувак, отстой, ява, нет, почему? Хорошо, почему это не было обновлено?
Мухаммед Салман

@MuhammadSalman Я не знаю .. Вам придется задать этот вопрос создателям Java. ;)
Кевин Круйссен

2

TI-Basic, 6 байтов

Prompt X:expr(Ans

Выражение принимается в качестве аргумента, а X вводится во время выполнения. В качестве альтернативы 8 байтов без expr:

Prompt X,u:u

Здесь оба аргумента вводятся во время выполнения.


2

Октава , 47 38 37 байт

Сэкономил много байтов, взяв второй ввод в виде строки вместо числа.

@(x,c)eval(strrep(x,'x',['*(',c,41]))

Попробуйте онлайн!

Объяснение:

Довольно прямо вперед: Заменить xна (c), где cнаходится второй вход, и оценить. Паретезы необходимы, потому что в Октаве -8^2 == -64.




1

Рубин , 43 41 байт

->p,x{eval p.gsub('^','**').gsub'x','*x'}

Попробуйте онлайн!

Сохранено два байта благодаря @ Mr.Xcoder


Поскольку ответа на Ruby пока нет, я добавил его. НВМ был один, который использовал другой подход

Пояснение:

->p,x{                    # lambda function that takes two arguments p and x
    eval(                 # eval 
        p.gsub(           # replace all instance of 
            '^' , '**'    # `^` with `**` (use for raised to power of)
        )                 # end gsub
        .gsub(            # start another replace all
            'x' , '*x'    # replace all instances of `x` with `*x`
        )                 # end the replace function
    )                     # end eval function
}                         # end lambda function


1

Excel, 36 + 2 байта, неконкурентный

Оценить текстовое поле как формулу не так просто в Excel. Существует скрытая =EVALUATE()функция, которая может быть вызвана путем определения имени.

В Excel 2007, Формулы> Определить имя. Определить имя с именем E, со ссылкой на:

=EVALUATE(SUBSTITUTE(A1,"x","*"&B1))

Затем, при вводе формулы в A1, xзначение в B1, ввод =Eв C1возвращает ожидаемый результат.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.