数学表达式中“ /”和“÷”之间的历史差异


33

介绍:

在此处输入图片说明

受到关于表达式的讨论的启发,讨论已经进行了很多年。6÷2(1+2)

使用表达式,数学家将很快看到正确答案是,而具有简单数学背景的人从学校毕业后将很快看到正确答案是。那么,这种争议何在呢?因此得出不同的答案呢?在编写方式时有两个相互冲突的规则。一种是由于零件,一种是由于分隔符号。6÷2(1+2)196÷2(1+22(÷

虽然这两个数学家和“普通人”将使用PEMDAS(括号-指数-司/乘法-加法/减法),数学家表达被这样下面评价,因为是一样例如单项式又名“ 由于并置的隐式乘法导致的单个项 ”(因此in的一部分),其计算结果将不同于(二项式又称为两个项):2(32X2PPEMDAS2×3

6÷21个+2623661个

而对于“普通人”,和将是相同的(因此是in的一部分),因此他们将改用它:232×3MDPEMDAS

6÷21个+26/2×1个+26/2×33×39

但是,即使我们将原始表达式写为,由于使用除法符号仍然存在一些争议。在现代数学中,和符号的含义完全相同:除法。有些规则预先1918年有关司符号††状态,它有比区间符号不同的含义。这是因为过去的意思是“ 将左边的数字/表达式除以右边的数字/表达式 ” 。因此等于或。在这种情况下6÷2×1个+2÷/÷÷/÷一种÷b一种/b一种b6÷2×1个+2 会在1918年之前被人们这样评估:

6÷2×1个+262×1个+262×3661个

†:尽管我找到了多个资料来解释÷过去的用法(请参阅下面的†††),但我无法找到确切的证据证明这种情况在1918年左右发生了改变。但是出于这一挑战,我们假设1918年是一个转折点,在这里÷/开始意味着同一件事,它们在过去有所不同。

††:其它符号也已经在过去的部门使用,如:在1633(或现在仍然在荷兰和其他欧洲非英语国家,因为这是我个人在小学的xD学会),或)在1540年代。但是对于这一挑战,我们仅关注1918年前的obelus符号的含义÷
†††:来源:本文一般。而关于前1918年的规则÷中提到:这个美国数学月刊从1917年2月的文章 ; 这本德国 Teutsche代数书从1659年第9 第76页开始 ; 是代数的第一本书从1895年第46页[48/189]

有点题外话:关于该表达式的实际讨论:绝对不要这样写!如果问题不清楚,正确答案是无关紧要的。 *点击“关闭,因为不清楚您要问什么”按钮*
根据记录,即使是不同版本的Casio计算器也不知道如何正确处理此表达式:
在此处输入图片说明

挑战:

您将获得两个输入:

  • 仅由符号组成的(有效)数学表达式 0123456789+-×/÷()
  • 一年

然后,您将基于年份输出数学表达式的结果(在,÷使用时会有所不同,但在时,会使用完全相同的)。ÿË一种[R<1918年/ÿË一种[R1918年

挑战规则:

  • 您可以假定数学表达式有效,并且仅使用符号0123456789+-×/÷()。这也意味着您无需处理幂运算。(如果允许打高尔夫球或您的语言仅支持ASCII,则也可以将×÷(即*%)使用其他符号。)
  • 如果这有助于(也许是手动的)表达式求值,则可以在输入表达式中添加空格分隔符。
  • I / O是灵活的。输入可以是字符串,字符数组等。年份可以是整数,日期对象,字符串等。输出将是十进制数。
  • 您可以假设将没有0个测试用例的划分。
  • 您可以假设input-expression中的数字为非负数(因此您不必处理将-负号与减号区分-)。但是,输出仍然可以为负!
  • 您可以假设N(将始终写为N×(。我们只专注于师符号的第二个争议/VS ÷这一挑战。
  • 十进制输出值的精度至少应为三个十进制数字。
  • 如果输入表达式包含多个÷(即4÷2÷2)与ÿË一种[R<1918年,它们被评价是这样的:4÷2÷242241个4。(或者换句话说:数字4除以表达式2÷2,其中表达式2÷2依次表示数字2除以数字2
  • 请注意,这种方式÷隐式起作用意味着它的操作符优先于×/(请参见测试用例4÷2×2÷3)。
  • 你可以假设输入年份的范围内[00009999]

一般规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此允许您使用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))

Answers:


25

R68 66字节

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

在线尝试!

预计等号=,而不是÷*代替×

该代码利用了一些讨厌的运算符重载,利用了一个事实,=即从右到左的运算符具有非常低的优先级(我们希望从1918年前开始的确切行为÷),而R保持原来的优先级。超载。剩下的工作会由自动为我们完成eval

另外,这是使用terser语法实现的完全相同的方法。这次,我们的特殊除法运算符为tilde(~):

朱莉娅0.7,51字节

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

在线尝试!


3
`=`=`/`是恶魔般的!很好的解决方案!
格里高尔

uuugggghhh我有相同的想法。las,您击败了我很多。在线尝试
朱塞佩

尽管目前尚无代码高尔夫语言的答案,但我接受您的Julia答案为目前最短的答案。如果发布较短的答案,则将来可能会改变。
凯文·克鲁伊森

6

的JavaScript(ES6), 130 129  120个字节

@ScottHamper节省了9个字节

将输入作为(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)

在线尝试!

怎么样?

处理叶表达式

HË%ÿ

ÿ<1918年X%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)

ÿ1918年%/

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))
Scott Hamper

@ScottHamper非常好。“从右到左”应该敲响钟声……但是没有。
阿尔诺

5

蟒3.8(预发布)324个 310 306字节

lambda s,y:eval((g(s*(y<1918))or s).replace('%','/'))
def g(s):
 if'%'not in s:return s
 l=r=j=J=i=s.find('%');x=y=0
 while j>-1and(x:=x+~-')('.find(s[j])%3-1)>-1:l=[l,j][x<1];j-=1
 while s[J:]and(y:=y+~-'()'.find(s[J])%3-1)>-1:r=[r,J+1][y<1];J+=1
 return g(s[:l]+'('+g(s[l:i])+')/('+g(s[i+1:r])+')'+s[r:])

在线尝试!

%代替÷*代替×


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

蒂奥


3
很好的主意。但是,您遇到的问题是4%2%2在两种情况下均返回1。(鉴于它应该在1918年之前返回4)
达达

是的,我暂时不能再看
Nahuel Fouilleul

1
@Dada,已修复(+ 50bytes)
Nahuel Fouilleul

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调车场infix评估程序,做了少量修改。÷是具有可变优先级的运算符:在<1918模式下低于所有其他内容(但有括号),在> = 1918模式下高于所有其他内容(但不包括括号)。对于<1918,满足4÷2÷2规范,它也是“右关联”(或左?),并且通过使÷优先级为负,然后在评估期间将任何优先级<0视为关联,来“伪造”关联。打高尔夫球的空间更大,但是我认为这是一个不错的选择。

在play.rust-lang.org上取消投放


您真的需要那么多空格吗?我认为大部分可以删除。
ivzem

@ivzem是个好点,但仍然比python大3倍
别忘了
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.