Историческая разница между `/` и `÷` в математических выражениях


33

Введение:

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

Вдохновлен дискуссией, которая продолжается уже много лет относительно выражения 6÷2(1+2) .

С выражением 6÷2(1+2) математики быстро увидят, что правильный ответ - 1 , тогда как люди с простым математическим образованием из школы быстро увидят, что правильный ответ - 9 . Так откуда же этот спор и, следовательно, разные ответы? В том, как написано 6÷2(1+2) есть два противоречивых правила . Один из-за части 2(, а другой из-за символа деления ÷.

Хотя и математики, и «обычные люди» будут использовать PEMDAS (скобки - экспоненты - деление / умножение - сложение / вычитание), для математиков выражение оценивается так, как показано ниже, потому что 2(3) аналогично, например, 2x2 моному также известный как « один член , обусловленные подразумеваемые умножения на противопоставлении » (и , следовательно , часть Pв PEMDAS), которые будут оценены иначе , чем 2×(3) (а биномиальные ака два термины):

6÷2(1+2)62(3)661

Принимая во внимание, что для «обычных людей» 2(3) и 2×(3) будут одинаковыми (и, следовательно, частью MDin PEMDAS), поэтому они будут использовать это вместо:

6÷2(1+2)6/2×(1+2)6/2×33×39

6÷2×(1+2)÷/÷÷/÷a÷b(a)/(b)ab6÷2×(1+2)

6÷2×(1+2)62×(1+2)62×3661

†: хотя я нашел несколько источников, объясняющих, как ÷это использовалось в прошлом (см. ††† ниже), я не смог найти убедительных доказательств того, что это изменилось где-то в 1918 году. Но ради этого испытания мы предполагаем, что 1918 год был поворотный момент, когда ÷и /начинает означать то же самое, где они отличались в прошлом.

††: Другие символы также использовались в прошлом для разделения, как :в 1633 году (или сейчас все еще в Нидерландах и других европейских не говорящих по-английски странах, поскольку это то, что я лично выучил в начальной школе xD) или )в 1540-е гг. Но для этого вызова мы сосредоточимся только на значении символа обелуса до 1918 года ÷.
†††: Источники: эта статья в целом . А до 1918 года правила в отношении ÷упоминаются: этой Американский Математический Monthly статью с февраля 1917 года ; эта немецкая книга по тевчской алгебре от 1659 г., стр. 9 и стр. 76 ; это первая книга по алгебрес 1895 г., стр. 46 [48/189] .

Немного не по теме: что касается фактического обсуждения этого выражения: оно никогда не должно быть написано, как это, во-первых! Правильный ответ не имеет значения, если вопрос неясен. * Кликает кнопку «закрыть, потому что неясно, что вы спрашиваете» * .
И, к слову, даже разные версии калькуляторов Casio не знают, как правильно справиться с этим выражением:
введите описание изображения здесь

Вызов:

Вам дают два входа:

  • (Действительное) математическое выражение, состоящее только из символов 0123456789+-×/÷()
  • Год

÷year<1918/year1918

Правила соревнований:

  • Вы можете предположить, что математическое выражение является действительным и использует только символы 0123456789+-×/÷(). Это также означает, что вам не придется иметь дело с возведением в степень. (Вам также разрешается использовать другие символы для ×или ÷(то есть *или %), если это помогает игре в гольф или если ваш язык поддерживает только ASCII.)
  • Вам разрешается добавлять разделители пробелов к выражению ввода, если это помогает (возможно, вручную) вычислить выражение.
  • Ввод / вывод является гибким. Входные данные могут быть в виде строки, символьного массива и т. Д. Год может быть в виде целого числа, объекта даты, строки и т. Д. Выходными данными будет десятичное число.
  • Вы можете предположить, что не будет никакого деления на 0 тестовых случаев.
  • Вы можете предположить, что числа во входном выражении будут неотрицательными (поэтому вам не придётся иметь дело с разграничением -как отрицательного символа, так и -символа вычитания). Однако выходной сигнал все еще может быть отрицательным!
  • Вы можете предположить, N(что всегда будет написано как N×(вместо. Мы сосредоточимся только на втором противоречии символов деления /против ÷этого испытания.
  • Десятичные выходные значения должны иметь точность не менее трех десятичных цифр.
  • ÷4÷2÷2year<19184÷2÷242241442÷22÷222
  • ÷×/4÷2×2÷3
  • [0000,9999]

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте придумать как можно более короткий ответ для «любого» языка программирования.
  • Стандартные правила применяются к вашему ответу с правилами ввода / вывода по умолчанию , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода (например, TIO ).
  • Кроме того, добавление объяснения для вашего ответа настоятельно рекомендуется.

Тестовые случаи:

Input-expression:   Input-year:   Output:      Expression interpretation with parenthesis:

6÷2×(1+2)           2018          9            (6/2)×(1+2)
6÷2×(1+2)           1917          1            6/(2×(1+2))
9+6÷3-3+15/3        2000          13           ((9+(6/3))-3)+(15/3)
9+6÷3-3+15/3        1800          3            (9+6)/((3-3)+(15/3))
4÷2÷2               1918          1            (4/2)/2
4÷2÷2               1900          4            4/(2/2)
(1÷6-3)×5÷2/2       2400          -3.541...    ((((1/6)-3)×5)/2)/2
(1÷6-3)×5÷2/2       1400          1.666...     ((1/(6-3))×5)/(2/2)
1×2÷5×5-15          2015          -13          (((1×2)/5)×5)-15
1×2÷5×5-15          1719          0.2          (1×2)/((5×5)-15)
10/2+3×7            1991          26           (10/2)+(3×7)
10/2+3×7            1911          26           (10/2)+(3×7)
10÷2+3×7            1991          26           (10/2)+(3×7)
10÷2+3×7            1911          0.434...     10/(2+(3×7))
4÷2+2÷2             2000          3            (4/2)+(2/2)
4÷2+2÷2             1900          2            4/((2+2)/2)
4÷2×2÷3             9999          1.333...     ((4/2)×2)/3
4÷2×2÷3             0000          3            4/((2×2)/3)
((10÷2)÷2)+3÷7      2000          2.928...     ((10/2)/2)+(3/7)
((10÷2)÷2)+3÷7      1900          0.785...     (((10/2)/2)+3)/7
(10÷(2÷2))+3×7+(10÷(2÷2))+3×7
                    1920          62           (10/(2/2))+(3×7)+(10/(2/2))+(3×7)
(10÷(2÷2))+3×7+(10÷(2÷2))+3×7
                    1750          62           (10/(2/2))+(3×7)+(10/(2/2))+(3×7)
10÷2/2+4            2000          6.5          ((10/2)/2)+4
10÷2/2+4            0100          2            10/((2/2)+4)
9+6÷3-3+15/3        9630          13           9+(6/3)-3+(15/3)
9+6÷3-3+15/3        0369          3            (9+6)/(3-3+(15/3))

Ответы:


25

R , 68 66 байт

function(x,y,`=`=`/`)eval(parse(t=`if`(y<1918,x,gsub('=','/',x))))

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

Ожидает знак равенства =вместо ÷и *вместо ×.

Код использует некоторую неприятную перегрузку операторов, используя тот факт, что =это оператор справа налево с очень низким приоритетом (точное поведение, которое мы хотим от до 1918 г. ÷), и R сохраняет свой первоначальный приоритет, когда он перегружен. Остальное автоматически делается для нас eval.

В качестве бонуса, здесь тот же самый точный подход, реализованный в более кратком синтаксисе. На этот раз наш специальный оператор деления - это тильда ( ~):

Юлия 0,7 , 51 байт

~=/;f(x,y)=eval(parse(y<1918?x:replace(x,'~','/')))

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


3
`=`=`/`это дьявольское! Отличное решение!
Грегор

У меня были мысли в том же духе. Увы, ты меня сильно побил. Попробуйте онлайн
Джузеппе

Хотя пока еще нет ответов на языках Codegolf, я принимаю ваш ответ Джулии как самый короткий на данный момент. Возможно, это изменится в будущем, если будет опубликован более короткий ответ.
Кевин Круйссен

6

JavaScript (ES6),  130 129  120 байтов

Сохранено 9 байт благодаря @ScottHamper

Принимает вход как (year)(expr). Ожидает %и *вместо ÷и ×.

y=>g=e=>(e!=(e=e.replace(/\([^()]*\)/,h=e=>eval(e.split`%`.reduceRight((a,c)=>y<1918?`(${c})/(${a})`:c+'/'+a))))?g:h)(e)

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

Как?

Обработка листовых выражений

he%y

y<1918X%Y(X)/(Y)

Примеры:

  • 8%2становится (8)/(2), чья упрощенная форма8/2
  • 2+3%3+2 становится (2+3)/(3+2)
  • 8%2%2становится (8)/((2)/(2)), чья упрощенная форма8/(2/2)

y1918%/

h = e =>                    // e = input string
  eval(                     // evaluate as JS code:
    e.split`%`              //   split e on '%'
    .reduceRight((a, c) =>  //   for each element 'c', starting from the right and
                            //   using 'a' as the accumulator:
      y < 1918 ?            //     if y is less than 1918:
        `(${c})/(${a})`     //       transform 'X%Y' into '(X)/(Y)'
      :                     //     else:
        c + '/' + a         //       just replace '%' with '/'
    )                       //   end of reduceRight()
  )                         // end of eval()

Работа с вложенными выражениями

h

g

g = e => (            // e = input
  e !=                // compare the current expression with
    ( e = e.replace(  // the updated expression where:
        /\([^()]*\)/, //   each leaf expression '(A)'
        h             //   is processed with h
      )               // end of replace()
    ) ?               // if the new expression is different from the original one:
      g               //   do a recursive call to g
    :                 // else:
      h               //   invoke h on the final string
)(e)                  // invoke either g(e) or h(e)

Вот версия, hкоторая на 9 байт короче:h=e=>eval(e.split`%`.reduceRight((a,c)=>y<1918?`(${c})/(${a})`:c+'/'+a))
Скотт Хэмпер

@ ScottHamper Очень мило. «Справа налево» должен был звонить в колокольчик ... но это не так.
Арно


1

Perl 5, 47 97 95 байт

/ /;$_="($`)";$'<1918?s-%-)/(-g:y-%-/-;$_=eval

$_="($F[0])";1while$F[1]<1918&&s-\([^()]+\)-local$_=$&;s,%,)/((,rg.")"x y,%,,-ee;y-%-/-;$_=eval

TIO


3
Очень хорошая идея Тем не менее, у вас есть проблема, 4%2%2которая возвращает 1 в обоих случаях. (тогда как должно вернуться 4 до 1918 года)
Дада

это правда, я не могу больше смотреть на данный момент
Науэль Фуйе

1
@Dada, исправлено (+ 50 байт)
Науэль Фуий

1

Ржавчина - 1066 860 783 755 740 байт

macro_rules! p{($x:expr)=>{$x.pop().unwrap()}}fn t(s:&str,n:i64)->f64{let (mut m,mut o)=(vec![],vec![]);let l=|v:&Vec<char>|*v.last().unwrap();let z=|s:&str|s.chars().nth(0).unwrap();let u=|c:char|->(i64,fn(f64,f64)->f64){match c{'÷'=>(if n<1918{-1}else{6},|x,y|y/x),'×'|'*'=>(4,|x,y|y*x),'-'=>(2,|x,y|y-x),'+'=>(2,|x,y|y+x),'/'=>(5,|x,y|y/x),_=>(0,|_,_|0.),}};macro_rules! c{($o:expr,$m:expr)=>{let x=(u(p!($o)).1)(p!($m),p!($m));$m.push(x);};};for k in s.split(" "){match z(k){'0'..='9'=>m.push(k.parse::<i64>().unwrap() as f64),'('=>o.push('('),')'=>{while l(&o)!='('{c!(o,m);}p!(o);}_=>{let j=u(z(k));while o.len()>0&&(u(l(&o)).0.abs()>=j.0.abs()){if j.0<0&&u(l(&o)).0<0{break;};c!(o,m);}o.push(z(k));}}}while o.len()>0{c!(o,m);}p!(m)}

У Rust нет ничего похожего на 'eval', так что это немного сложно. По сути, это стандартная версия информативного оценщика Djisktra с небольшим изменением. ÷ - оператор с переменным приоритетом: ниже, чем все остальное (кроме скобок) в режиме <1918, выше, чем все остальное в режиме> = 1918. Кроме того, «<ассоциировано справа» (или слева?) Для <1918, чтобы соответствовать спецификации 4 ÷ 2 ÷ 2, и ассоциация «фальсифицируется», делая ÷ приоритет отрицательным, а затем во время оценки обрабатывает любой приоритет <0 как связанный. Там больше места для игры в гольф, но это хороший проект, я думаю.

Разрушенный на play.rust-lang.org


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

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