数式における「/」と「÷」の歴史的な違い


33

前書き:

ここに画像の説明を入力してください

6÷2(1+2)に関する長年の議論に触発されました。

6÷2(1+2)、数学者は正解が1であることがすぐにわかります。一方、学校からの単純な数学の背景を持つ人は、正解が9ことがすぐにわかります。それで、この論争とそれによる異なる答えはどこから来るのでしょうか?6÷2(1+2)記述方法には2つの矛盾するルールがあります。1つは部品によるもの2(で、もう1つは分割記号によるもの÷です。

数学と「普通の人々 」の両方が使用されますが、PEMDAS( -指数精度-部門/乗算-カッコ加算/減算を)ので、数学者のための式は、以下のように評価されて2(3)だけ例えばのようなものである2x2の単項式別名「並置による暗黙の乗算による単一項」(したがって、Pinの一部PEMDAS)。これは、2×(3)(二項別名、2項)とは異なる方法で評価されます。

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)として記述したとしても、除算記号を使用しているため、まだ議論の余地があります÷。現代の数学では、/および÷記号の意味はまったく同じです:除算。いくつかのルールは、事前に1918 分割シンボルに関する÷††それは分割シンボルとは異なる意味を持っていたこと状態/。これは、ある÷意味「するために使用右の数字/発現と左の数/表現を分割†††。したがってa÷bは、(a)/(b)またはab今。この場合、1918年以前の人々は6÷2×(1+2)を次のように評価します。

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

†:÷過去の使用方法を説明する複数の情報源を見つけましたが(下記の†††を参照)、これが1918年ごろにどこかで変更されたことを明確に証明することはできませんでした。ターニングポイント÷/、彼らは過去に異なっても同じことを意味し始めて。

††:その他の記号も同様に、部門の過去に使用されている:か(これは私が個人的に小学校のxDさんに学んだことがあるため、オランダなどヨーロッパ以外の英語圏の国ではまだ今か)1633年)に1540年代。しかし、この課題では、1918年以前のobelusシンボルの意味にのみ焦点を当てています÷
†††:出典:この記事全般。そしてに関する事前1918ルール÷で言及されています。このザ・アメリカ数学月間の1917年2月からの記事1659 ページ9および76 ページからのドイツのこの代数この代数の最初の本1895ページ46 [48/189]から

少しオフトピック:この表現に関する実際の議論に関して:そもそもこのように書かれてはいけません!質問が不明確な場合、正しい答えは無関係です。 *「質問内容が不明なため閉じる」ボタンをクリックします*
そして記録のために、カシオ計算機の異なるバージョンでさえ、この式を適切に処理する方法を知りません:
ここに画像の説明を入力してください

チャレンジ:

次の2つの入力が与えられます。

  • 記号のみで構成される(有効な)数式 0123456789+-×/÷()
  • 一年

そして、年に基づいて数式の結果を出力します(どこ÷で使用されるかは異なりますyear<1918が、正確に同じ使用され/たときにyear1918)。

チャレンジルール:

  • 数式が有効であり、シンボルのみを使用すると仮定できます0123456789+-×/÷()。これは、べき乗を扱う必要がないことも意味します。(または、ゴルフに役立つ場合、または言語がASCIIのみをサポートしている場合は、×or ÷*またはor %)に異なる記号を使用することもできます。)
  • 式の評価(おそらく手動)に役立つ場合は、input-expressionにスペース区切り文字を追加できます。
  • I / Oは柔軟です。入力は文字列、文字配列などとして使用できます。年は整数、日付オブジェクト、文字列などとして使用できます。出力は10進数です。
  • 0個のテストケースによる除算は行われないと想定できます。
  • input-expressionの数値が非負であると想定できます(したがって-、負のシンボル-と減算シンボルを区別する必要はありません)。ただし、出力はマイナスになる可能性があります!
  • 代わりにN(常に記述されると仮定できN×(ます。我々は唯一の分割シンボルの第2の論争に焦点を当てます/÷この挑戦インチ
  • 10進数の出力値には、少なくとも3桁の10進数の精度が必要です。
  • 入力式に複数÷(すなわち4÷2÷2)が含まれ、year<1918 4 ÷ 2 ÷ 2 4のように評価されます。4÷2÷2422414。(または言葉で:番号4は式2÷2で除算され、式2÷2ターン手段では、数2数によって分割される2)。
  • この方法÷は暗黙的に動作することを意味し、演算子の優先順位が×and よりも高いことに注意してください/(テストケースを参照4÷2×2÷3
  • 入力年が範囲内にあると仮定できます [0000,9999]

一般的なルール:

  • これはであるため、バイト単位の最短回答が優先されます。
    コードゴルフ言語では、コードゴルフ以外の言語で回答を投稿しないようにしてください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。
  • デフォルトの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))

回答:


25

R68 66バイト

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

オンラインでお試しください!

期待するの等号=の代わりに、÷*の代わりに、×

このコードは、いくつかの厄介な演算子のオーバーロードを利用し=、右から左への優先順位が非常に低い(1918年以前から必要な正確な動作)という事実を利用して÷、Rは元の優先順位を保持します過負荷。残りは自動的に行われますevalます。

ボーナスとして、terser構文で実装されたのとまったく同じアプローチがあります。今回は、特別な除算演算子はチルダ(~)です。

ジュリア0.7バイト

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

オンラインでお試しください!


3
`=`=`/`悪魔です!素晴らしい解決策!
グレゴール

uuugggghhh同じ行について考えていました。悲しいかな、あなたは私にそれをかなり打ち負かしました。オンラインで試す
ジュゼッペ

codegolf言語にはまだ答えがありませんが、ジュリアの答えを今のところ最短で受け入れています。短い回答が投稿された場​​合、これはもちろん将来変更される可能性があります。
ケビンクルーッセン

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 葉の表現を期待する e入力として%、年の規則に従ってすべてのシンボルを処理しますy (親スコープで定義)および結果の文字列を評価します。

もし y<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)

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

これはh9バイト短いバージョンです:h=e=>eval(e.split`%`.reduceRight((a,c)=>y<1918?`(${c})/(${a})`:c+'/'+a))
Scott Hamper

@ScottHamperとてもいい。「右から左」にはベルが鳴るはずですが、そうではありませんでした。
アーナルド

5

Python 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

TIO


3
とてもいいアイデアです。ただし、4%2%2どちらの場合でも1を返す問題があります。(一方、1918年以前の4を返す必要があります)
ダダ

本当だ、今はもう見られない
ナウエル・フイユル

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」のようなものがないため、これは少し難しいです。基本的に、これは湿地標準のジスクトラシャンティングヤード中置式評価プログラムであり、わずかな変更が加えられています。÷は、可変優先順位を持つ演算子です。<1918モードでは他のすべて(括弧以外)より低く、> = 1918モードでは他のすべてよりも高くなります。また、<1918が4÷2÷2仕様を満たすために「右関連」(または左?)であり、÷優先順位を負にすることで関連が「偽造」され、評価中に優先順位<0を関連として処理します。ゴルフの余地はもっとありますが、これは良いドラフトだと思います。

play.rust-lang.orgでゴルフをしていない


そんなに空白が本当に必要ですか?そのほとんどは削除できると思います。
ivzem

@ivzem良い点が、パイソンより大きくまだ3回
明るいドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.