Решить линейное уравнение


12

Это вызов, но с лучшей спецификацией.

спекуляция

Ваша программа возьмет линейное уравнение, содержащее одну переменную, xи выведет значение x.

Ввод / Разбор

  • Входные данные будут содержать только числа, операторы, скобки ( ()) xи =знак (это означает отсутствие пробелов).
  • Круглая скобка всегда будет сбалансированной.
  • Всегда будет хотя бы 1 x. xМожет предшествовать число.
  • Все уравнения точно будут иметь один результат.

Число может быть определено, выполнив следующие действия. Номер может быть определен с помощью регулярного выражения: -?(\d+(\.\d+)?|\.\d+).


Если вы не говорите регулярное выражение: цифра определяется как 0-9

  1. Может иметь -в начале, что означает отрицательный
  2. Тогда могут быть некоторые цифры. Если они не состоят из цифр, будет десятичная точка
  3. Если существует десятичная точка, за ней будет следовать хотя бы одна цифра

Наибольшее число / значение будет определяться возможностями вашего языка.


Оператор является любой из: +-*/они всегда будут появляться между числами, и или скобка

это означает (5)(5)недопустимый ввод для простоты.


Круглая скобка всегда будет содержать правильное выражение (допустимая комбинация чисел и / или операторов) внутри них. «Сбалансированная» скобка определяется как каждая (будет иметь связанный закрытие)

оценка

  • Порядок операций должен соблюдаться, и приоритеты (от наивысшего к низшему):
    • Круглая скобка (наиболее глубоко вложенная в первую очередь)
    • Умножение и деление
    • Сложение и вычитание
  • Если встречаются два оператора с одинаковым приоритетом, предпочтительнее идти налево -> направо

Выход

Вы должны вывести результат каким-то образом. Если вы не выводите только результат числа, уточните в своем ответе, как выводится результат. Ваш выходной формат должен быть согласованным. Вывод может быть десятичным, но он всегда будет рациональным, точность ограничена точностью вашего языка. Только если ваш язык не поддерживает арифметику с плавающей запятой, вам не нужно ее поддерживать.

правила

  • Разрешены встроенные средства, упрощающие эту задачу, но вы должны четко добавить [uses built-in]в заголовок ответа. Это освобождает ваш ответ от победы
  • «Встроенные тривиализирующие эту задачу» - это любое из:
    • Нечто, принимающее уравнение и выводящее значение для переменной
    • Что-то, что полностью упростит уравнение
    • Использование evalили связанная функция для выполнения значительного количества анализа. Использование evalи связанные с ними функции запрещены, если они используются (с минимальной модификацией входных данных) для решения линейных уравнений.
    • Если вы сомневаетесь, просто спросите в комментарии.
  • Встроенные модули, которые разбирают уравнения, разрешены

Примеры

3+4=x
7

4+x=5
1

3+3*3=x
12

3x-4=7+2x
11

3--1=x
4

3*(2+4x)=7x-4
-2

1.2+2.3x=5.8
2

10=4x
2.5

НЕВЕРНЫЕ Входы:

(5)(4)=x  no operator between (5) and (4)
5(x+3)=2  no operator 5 and (...)
x=y       the only variable is x
4=3       there is no x
x+3=x-7   no solution
x=x       infinite solutions
+5=x      + is not an unary operator. -5=x would be valid though
1/(x-3)=5 Nonlinear
3/x       Nonlinear

8
Вы говорите, что встроенные модули дисквалифицируют ваше представление, но уточняют это, чтобы относиться только к операциям, которые выполняют решение уравнений и анализ и тому подобное. Я думаю, что было бы понятнее использовать другой термин, поскольку я считаю любую именованную операцию встроенной.
xnor

Насколько точными должны быть ответы?
flawr

@MrPublic Ваша программа будет принимать линейное уравнение, содержащее одну переменную ...
Луис Мендо,

Кроме того, evalсчитается ли JavaScript тривиальным вызовом? Кроме того, формы new Function(...)подсчета?
Конор О'Брайен

@ CᴏɴᴏʀO'Bʀɪᴇɴ зависит от того, для чего вы его используете. Но если предположить , что вы используете JavaScript я не вижу , как это будет упрощать проблему так уверен
Downgoat

Ответы:


3

JavaScript ES6, 246 байт

Еще можно поиграть в гольф, но, по крайней мере, это решение!

C=a=>new Function("x","return "+a.replace(/(\d)x/g,"$1*x"));n=>{n=n.split("=");t=Math.abs,r=C(n[0]),c=C(n[1]),a=0,i=r(a)-c(a);a++;v=r(a)-c(a);o=t(i)<t(v)?-1:1;for(u=1/0;r(a)!==c(a);)a+=o,e=t(r(a)-c(a)),e>u&&(u=1/0,o/=10),u=Math.min(e,u);return a}

Назовите функцию, n=>{n=n.split("=")...чтобы использовать ее.

Hyper-ungolfed:

function solveLinear(equation){
    equation = equation.split("=");
    var abs = Math.abs;
    var LHS = convertToFunction(equation[0]), RHS = convertToFunction(equation[1]);
    var pivot = 0;
    var dir;
    var dir1 = LHS(pivot) - RHS(pivot);
    pivot++;
    var dir2 = LHS(pivot) - RHS(pivot);
    if(abs(dir1)<abs(dir2)) dir = -1;
    else dir = 1;
    var dif, minDif = Infinity;
    while(LHS(pivot) !== RHS(pivot)){
        pivot += dir;
        dif = abs(LHS(pivot) - RHS(pivot));
        if(dif > minDif){
            minDif = Infinity;
            dir /= 10;
        }
        minDif = Math.min(dif, minDif);
        console.log(pivot,dir,dif,minDif);
    }
    return {
        x: pivot,
        LHS: LHS,
        RHS: RHS
    };
}

Это использует сводный подход. (Я не уверен, что это то, что называется алгоритмом, просто придуманное мной имя.) Сначала он собирает, какое направление искать с нуля (т. Е. В каком направлении будут пересекаться склоны двух сторон уравнений) и ищет значение. Как только он находит точку минимальной разницы, он идет к этой точке и уменьшает приращение поиска. В конечном итоге это дает точное решение, которое нам нужно.


Я думаю, что вы могли бы побриться, используя синтаксис eval + ES6 вместо Function new
Ven

2

JavaScript (Node.js) , 106 93 байта

a=>eval(`f=x=>${a[R='replace'](/(\d)x/g,"$1*x")[R]("=","-(")[R](/-/g,"+-")})`)(0)/(f(0)-f(1))

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

-13 байт благодаря @tsh

Ungolfed:

var h=a=>{
  a=a.replace(/(\d)x/g,"$1*x").replace("=","-(").replace("--","- -"); //get into an eval-able form
  var f=x=>eval(a+")");
  var df=(f(1)-f(0))/(1-0) //derivative or slope of the function
  var x=0;
  return x-(f(x)/df); //newton's method
}

Explaination:

Это решение работает по методу Ньютона для поиска корней. Код вычитает правую часть уравнения с левой стороны, так что , когда f(x)=0, xбудет равно значению Решаю для. Поэтому, когда мы найдем корень этой новой функции, это будет нашим желаемым xзначением. Затем он находит производную f'(x), находя наклон между двумя точками на функции. Затем эти значения просто вставляется в метод Ньютона , который гласит , для приближения корня x, x=x-(f(x)/f'(x))(в коде, мы используем 0 в качестве начального xзначения). Так как это находит корни, оно находит нашу xценность. А поскольку уравнение гарантированно будет линейным, аппроксимация будет точной.



1

Mathcad, [использует встроенный]

введите описание изображения здесь

Mathcad имеет два встроенных метода решения таких уравнений:

  • Символьный решатель (использует ключевое слово решить)
  • Solve Block (работает как в числовом, так и в символическом режимах). Блок Solve начинается с ключевого слова Given, за которым следует набор выражений, определяющих условия интереса, и закрывается одним из решающих ключевых слов, например Find (который находит точное решение) или MinErr (который минимизирует ошибку между целью и любое решение).

Символический решатель вполне доволен y = x и возвращает решение x = y.

Для тех, кто не знаком с Mathcad, изображение ниже взято непосредственно из книги WYSIWYGish Mathcad 15. Изменение любого выражения, в котором они написаны, заставит Mathcad пересмотреть свой ответ и соответствующим образом обновить отображение.


Из праздного любопытства, почему отрицательные голоса? Я могу понять, что простота этого может быть в корне этого, но это, по сути, ничем не отличается от решения TI Basic, которое просто добавляет небольшой объем обработки ввода перед вызовом встроенного решателя, и все же это не был понижен
Стюарт Бруфф

1
Каково действительное количество байтов этой программы?
Джо Кинг

Скорее всего, отрицательные результаты объясняются тем, что ваше решение тривиально - см. «Что такое тривиальное решение?» на мета.

0

Аксиома, 214 байт [использует встроенный]

q(t:EQ POLY FLOAT):Any==(a:=[variables(lhs t),variables(rhs t)];a.1~=[x]and a.1~=[]=>%i;a.2~=[x]and a.2~=[]=>%i;a.1=[]and a.2=[]=>%i;a.1=[x]and degree(lhs t,x)>1=>%i;a.2=[x]and degree(rhs t,x)>1=>%i;rhs solve(t).1)

Для некоторой ошибки будет возвращено% i, для других типов ошибок функция остановлена ​​из системы, что-то еще, так как 1-2 кажется не языковым ... test:

(72) -> q(x+3=9)
   (72)  6.0
                                  Type: Complex Fraction Polynomial Float
(73) -> q(3+4=x)
   (73)  7.0
                                  Type: Complex Fraction Polynomial Float
(74) -> q(4+x=5)
   (74)  1.0
                                  Type: Complex Fraction Polynomial Float
(75) -> q(3+3*3=x)
   (75)  12.0
                                  Type: Complex Fraction Polynomial Float
(76) -> q(3*x-4=7+2*x)
   (76)  11.0
                                  Type: Complex Fraction Polynomial Float
(77) -> q(3--1=x)
  Line   1: q(3--1=x)
           .AB
  Error  A: Missing mate.
  Error  B: syntax error at top level
  Error  B: Possibly missing a )
   3 error(s) parsing
(77) -> q(3*(2+4*x)=7*x-4)
   (77)  - 2.0
                                  Type: Complex Fraction Polynomial Float
(78) -> q(1.2+2.3*x=5.8)
   (78)  2.0
                                  Type: Complex Fraction Polynomial Float
(79) -> q(10=4*x)
   (79)  2.5
                                  Type: Complex Fraction Polynomial Float
(80) -> q((5)(4)=x)
   Cannot find a definition or applicable library operation named 5
      with argument type(s)
                           PositiveInteger

  Perhaps you should use "@" to indicate the required return type,
  or "$" to specify which version of the function you need.
(80) -> q(5(x+3)=2 )
   (80)  %i
                                                    Type: Complex Integer
(81) -> q(x=y)
   (81)  %i
                                                    Type: Complex Integer
(82) -> q(4=3)
   (82)  %i
                                                    Type: Complex Integer
(83) -> q(x+3=x-7)
   >> Error detected within library code:
   inconsistent equation
protected-symbol-warn called with (NIL)
(83) -> q(x=x)
   >> Error detected within library code:
   equation is always satisfied
protected-symbol-warn called with (NIL)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.