Historischer Unterschied zwischen `/` und `÷` in mathematischen Ausdrücken


33

Einführung:

Bildbeschreibung hier eingeben

Inspiriert von einer Diskussion, die bereits seit vielen Jahren über den Ausdruck .6÷2(1+2)

Mit dem Ausdruck Mathematiker schnell, dass die richtige Antwort , während Menschen mit einem einfachen mathematischen Hintergrund aus der Schule schnell erkennen, dass die richtige Antwort . Woher kommt diese Kontroverse und damit die unterschiedlichen Antworten? Es gibt zwei widersprüchliche Regeln in der Schreibweise von . Eine wegen des Teils und eine wegen des Teilungssymbols .6÷2(1+2)196÷2(1+2)2(÷

Obwohl sowohl Mathematiker als auch "normale Leute" PEMDAS (Parenthesis - Exponents - Division / Multiplication - Addition / Subtraction) verwenden, wird der Ausdruck für Mathematiker wie folgt ausgewertet, da genau wie zum Beispiel ein Monom ist aka " ein einziger Term aufgrund impliziter Multiplikation durch Nebeneinanderstellung " (und daher Teil des In ), der anders ausgewertet wird als (ein Binom, aka zwei Terme):2(3)2x2 2 × ( 3 )PPEMDAS2×(3)

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

Während für „normale Leute“ und gleich sind (und daher Teil des Eingangs sind ), verwenden sie stattdessen Folgendes:2(3)2×(3)MDPEMDAS

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

Selbst wenn wir den ursprünglichen Ausdruck als , kann es aufgrund der Verwendung des Teilungssymbols dennoch zu Kontroversen kommen . In der modernen Mathematik haben die Symbole und genau die gleiche Bedeutung: Teilen. Einige Regeln vor 1918 bezüglich des Teilungssymbols †† besagen, dass es eine andere Bedeutung hatte als das Teilungssymbol . Dies ist so, weil es bedeutet " Teilen Sie die Zahl / den Ausdruck links mit der Zahl / dem Ausdruck rechts " ††† . Also wäre jetzt oder . In diesem Fall ist6÷2×(1+2)a b ( a ) / ( b ) a÷/÷÷/÷a÷b(a)/(b)ab6÷2×(1+2) würde von Leuten vor 1918 so bewertet werden:

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

†: Obwohl ich mehrere Quellen gefunden habe, die erklären, wie ÷in der Vergangenheit gearbeitet wurde (siehe ††† unten), konnte ich keinen endgültigen Beweis dafür finden, dass sich dies irgendwo um 1918 geändert hat der Wendepunkt, an dem ÷und zu /Beginn dasselbe bedeutete, wo sie sich in der Vergangenheit unterschieden.

††: In der Vergangenheit wurden auch andere Symbole für die Teilung verwendet, wie :1633 (oder jetzt noch in den Niederlanden und anderen nicht englischsprachigen Ländern in Europa, da ich dies in der Grundschule xD persönlich gelernt habe) oder )in die 1540er Jahre. Bei dieser Herausforderung konzentrieren wir uns jedoch nur auf die Bedeutung des Obelussymbols vor 1918 ÷.
†††: Quellen: dieser Artikel im Allgemeinen . Und die prä-1918 Regeln in Bezug ÷erwähnt in: dieser The American Mathematical Monthly Artikel vom Februar 1917 ; dieses deutsche Teutsche Algebra Buch von 1659 Seite 9 und Seite 76 ; Dies ist ein erstes Buch in der Algebraab 1895 Seite 46 [48/189] .

Etwas abseits des Themas: Bezüglich der eigentlichen Diskussion über diesen Ausdruck: Es sollte niemals so geschrieben werden! Die richtige Antwort ist irrelevant, wenn die Frage unklar ist. * Klicken Sie auf die Schaltfläche "Schließen, da nicht klar ist, wonach Sie fragen" * .
Und im Grunde wissen auch verschiedene Versionen von Casio-Rechnern nicht, wie man mit diesem Ausdruck richtig umgeht:
Bildbeschreibung hier eingeben

Herausforderung:

Sie erhalten zwei Eingaben:

  • Ein (gültiger) mathematischer Ausdruck, der nur aus den Symbolen besteht 0123456789+-×/÷()
  • Ein Jahr

Und Sie geben das Ergebnis des mathematischen Ausdrucks basierend auf dem Jahr aus (wobei ÷anders verwendet wird, wenn das , aber genau so verwendet wird, wie wenn das ).year<1918y e ein r 1918/year1918

Herausforderungsregeln:

  • Sie können davon ausgehen, dass der mathematische Ausdruck gültig ist und nur die Symbole verwendet 0123456789+-×/÷(). Dies bedeutet auch, dass Sie sich nicht mit Potenzierung befassen müssen. (Sie dürfen auch andere Symbole für ×oder ÷(dh *oder %) verwenden, wenn dies das Golfen erleichtert oder wenn Ihre Sprache nur ASCII unterstützt.)
  • Sie können dem Eingabeausdruck Leerzeichen hinzufügen, wenn dies die (möglicherweise manuelle) Auswertung des Ausdrucks erleichtert.
  • I / O ist flexibel. Die Eingabe kann als Zeichenfolge, Zeichenfeld usw. erfolgen. Das Jahr kann als Ganzzahl, Datumsobjekt, Zeichenfolge usw. erfolgen. Die Ausgabe erfolgt als Dezimalzahl.
  • Sie können davon ausgehen, dass es keine Division durch 0 Testfälle gibt.
  • Sie können davon ausgehen, dass die Zahlen im Eingabeausdruck nicht negativ sind (Sie müssen also nicht zwischen dem -negativen -und dem subtraktiven Symbol unterscheiden). Der Ausgang kann aber immer noch negativ sein!
  • Sie können davon ausgehen N(, dass N×(stattdessen immer geschrieben wird. Wir werden uns bei dieser Herausforderung nur auf die zweite Kontroverse der Divisionssymbole /gegen konzentrieren ÷.
  • Dezimal-Ausgabewerte sollten eine Genauigkeit von mindestens drei Dezimalstellen haben.
  • ÷4÷2÷2year<19184÷2÷242241442÷22÷22242÷22÷222
  • Beachten Sie, dass die Funktionsweise ÷implizit bedeutet, dass der Operator Vorrang vor ×und hat /(siehe Testfall ).4÷2×2÷3
  • Sie können davon ausgehen, dass das Eingabejahr im Bereich .[0000,9999]

Allgemeine Regeln:

  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
    Lassen Sie sich von Code-Golf-Sprachen nicht davon abhalten, Antworten mit Nicht-Codegolf-Sprachen zu veröffentlichen. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Antwort zu finden.
  • Für Ihre Antwort gelten Standardregeln mit Standard-E / A-Regeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methoden mit den richtigen Parametern und vollständige Programme vom Rückgabetyp, verwenden. Ihr Anruf.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu (z. B. TIO ).
  • Außerdem wird dringend empfohlen, eine Erklärung für Ihre Antwort hinzuzufügen.

Testfälle:

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

Antworten:


25

R , 68 66 Bytes

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

Probieren Sie es online!

Erwartet Gleichheitszeichen =statt ÷und *statt ×.

Der Code nutzt eine böse Überladung von Operatoren, wobei die Tatsache ausgenutzt wird, dass =es sich um einen Operator von rechts nach links mit sehr geringer Priorität handelt (genau das Verhalten, das wir vor 1918 wünschen ÷), und R behält seine ursprüngliche Priorität bei, wenn es ist überladen. Den Rest erledigt automatisch für uns eval.

Als Bonus wird hier derselbe exakte Ansatz in Terser-Syntax implementiert. Diesmal ist unser spezieller Divisionsoperator tilde ( ~):

Julia 0,7 , 51 Bytes

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

Probieren Sie es online!


3
`=`=`/`ist teuflisch! Tolle Lösung!
Gregor

uuugggghhh ich hatte gedanken in der gleichen linie. Ach, du hast mich ziemlich geschlagen. Versuchen Sie es online
Giuseppe

Obwohl es noch keine Antworten in Codegolf-Sprachen gibt, akzeptiere ich Ihre Julia-Antwort vorerst als die kürzeste. Es ist möglich, dass sich dies in Zukunft natürlich ändern wird, wenn eine kürzere Antwort veröffentlicht wird.
Kevin Cruijssen

6

JavaScript (ES6),  130 129  120 Byte

9 Bytes dank @ScottHamper eingespart

Übernimmt die Eingabe als (year)(expr). Erwartet %und *anstelle von ÷und ×.

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

Probieren Sie es online!

Wie?

Blattausdrücke verarbeiten

he%y

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

Beispiele:

  • 8%2wird (8)/(2), dessen vereinfachte Form ist8/2
  • 2+3%3+2 wird (2+3)/(3+2)
  • 8%2%2wird (8)/((2)/(2)), dessen vereinfachte Form ist8/(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()

Umgang mit verschachtelten Ausdrücken

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)

Hier ist eine Version h, die 9 Bytes kürzer ist:h=e=>eval(e.split`%`.reduceRight((a,c)=>y<1918?`(${c})/(${a})`:c+'/'+a))
Scott Hamper

@ScottHamper Sehr schön. 'Von rechts nach links' hätte klingeln sollen ... aber es hat nicht geklingelt.
Arnauld

5

Python 3.8 (Vorabversion) , 324 310 306 Byte

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:])

Probieren Sie es online!

Nimmt %statt ÷und *statt×


1

Perl 5, 47 97 95 Bytes

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

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

TIO


3
Sehr schöne Idee. Es liegt jedoch ein Problem vor, bei 4%2%2dem in beiden Fällen 1 zurückgegeben wird. (während es 4 vor 1918 zurückgeben sollte)
Dada

es ist wahr, ich kann im Moment nicht mehr schauen
Nahuel Fouilleul

1
@Dada, behoben (+ 50 Byte)
Nahuel Fouilleul

1

Rust - 1066 860 783 755 740 Bytes

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 hat so etwas wie 'eval' nicht, also ist das ein bisschen schwierig. Grundsätzlich handelt es sich hierbei um einen standardmäßigen Djisktra-Rangierhof-Infix-Evaluator mit einer geringfügigen Änderung. ÷ ist ein Operator mit variabler Priorität: niedriger als alles andere (außer Klammern) im Modus <1918, höher als alles andere im Modus> = 1918. Es ist auch "rechts assoziiert" (oder links?), Dass <1918 die 4 ÷ 2 ÷ 2-Spezifikation erfüllt, und die Assoziation wird "gefälscht", indem die making-Priorität negativ gemacht wird, und dann während der Bewertung, wenn eine Priorität <0 als assoziiert behandelt wird. Es gibt mehr Platz zum Golfen, aber ich denke, das ist ein guter Entwurf.

Ungolfed auf play.rust-lang.org


Brauchen Sie wirklich so viel Leerzeichen? Ich denke, das meiste könnte entfernt werden.
Ivzem

@ivzem guter Punkt, aber immer noch 3-mal größer als Python
Don Bright
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.