ความแตกต่างทางประวัติศาสตร์ระหว่าง `/` และ `÷ 'ในนิพจน์ทางคณิตศาสตร์


33

บทนำ:

ป้อนคำอธิบายรูปภาพที่นี่

แรงบันดาลใจจากการอภิปรายที่มีอยู่แล้วที่เกิดขึ้นมานานหลายปีเกี่ยวกับการแสดงออก2)6÷2(1+2)

ด้วยการแสดงออกที่คณิตศาสตร์ได้อย่างรวดเร็วจะเห็นว่าคำตอบที่ถูกต้องคือในขณะที่คนที่มีพื้นหลังเป็นคณิตศาสตร์ที่เรียบง่ายจากโรงเรียนอย่างรวดเร็วจะเห็นว่าคำตอบที่ถูกต้องคือ9ดังนั้นข้อโต้แย้งนี้และคำตอบที่ต่างกันมาจากไหน? มีสองกฎระเบียบที่ขัดแย้งกันในวิธีการที่เป็นลายลักษณ์อักษร หนึ่งเนื่องจากเป็นส่วนหนึ่งและเป็นหนึ่งเนื่องจากสัญลักษณ์การหาร6÷2(1+2)196÷2(1+2)2(÷

แม้ว่าทั้งนักคณิตศาสตร์และ 'คนธรรมดา' จะใช้PEMDAS (วงเล็บ - เลขชี้กำลัง - การหาร / การคูณ - การบวก / การลบ) สำหรับนักคณิตศาสตร์การแสดงออกจะได้รับการประเมินเช่นนี้ด้านล่างเพราะเป็นตัวอย่างเช่น monomial อาคา " คำเดียวเนื่องจากการคูณโดยนัยโดยการตีข่าว " (และดังนั้นส่วนหนึ่งของใน) ซึ่งจะได้รับการประเมินที่แตกต่างจาก (ทวินามอาคาสองคำ):2(3)2x2PPEMDAS2×(3)

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

ในขณะที่ 'คนธรรมดา',และจะเหมือนกัน (และเป็นส่วนหนึ่งของอิน) ดังนั้นพวกเขาจะใช้สิ่งนี้แทน:2(3)2×(3)MDPEMDAS

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

อย่างไรก็ตามแม้ว่าเราจะมีการเขียนการแสดงออกเดิม6÷2×(1+2)÷สามารถมียังคงมีความขัดแย้งเกิดจากการใช้สัญลักษณ์การแบ่ง ในคณิตศาสตร์สมัยใหม่สัญลักษณ์/และ÷มีความหมายเดียวกัน: แบ่ง กฎบาง pre-1918 เกี่ยวกับการแบ่งสัญลักษณ์÷††/รัฐว่ามันมีความหมายที่แตกต่างจากสัญลักษณ์การหาร เพราะนี่คือการ÷ใช้เพื่อหมายถึง " แบ่งจำนวน / การแสดงออกทางด้านซ้ายมีจำนวน / การแสดงออกทางด้านขวา " ††† ดังนั้น÷ แล้วจะเป็นa÷(a)/()หรือaตอนนี้ ซึ่งในกรณี6÷2×(1+2)จะได้รับการประเมินเช่นนี้โดยคน pre-1918:

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

†: แม้ว่าฉันจะพบหลายแหล่งที่อธิบายวิธีการ÷ใช้ในอดีต (ดู†††ด้านล่าง) แต่ฉันไม่สามารถหาข้อสรุปที่พิสูจน์ได้ว่าการเปลี่ยนแปลงนี้เกิดขึ้นที่ไหนสักแห่งในปี 2461 แต่สำหรับความท้าทายนี้เราถือว่า 2461 คือ จุดเปลี่ยนที่เริ่มต้น÷และ /หมายถึงสิ่งเดียวกันที่พวกเขาแตกต่างกันในอดีต

††: สัญลักษณ์อื่น ๆ นอกจากนี้ยังมีการใช้ในอดีตที่ผ่านมาสำหรับการแบ่งเช่น:ใน 1633 (หรือในขณะนี้ยังคงอยู่ในประเทศเนเธอร์แลนด์และประเทศในยุโรปอื่น ๆ ที่ไม่ใช่ภาษาอังกฤษตั้งแต่นี้คือสิ่งที่ผมได้เรียนรู้กับบุคคลในโรงเรียนประถมศึกษา xD) หรือ)ใน ปี 1540 แต่สำหรับความท้าทายนี้เราจะมุ่งเน้นไปที่ pre-1918 ÷ความหมายของสัญลักษณ์
†††: แหล่งที่มา: บทความนี้โดยทั่วไป และ pre-1918 กฎระเบียบเกี่ยวกับ÷กล่าวถึงใน: นี้อเมริกันคณิตศาสตร์เดือนบทความจากกุมภาพันธ์ 1917 ; หนังสือภาษาเยอรมัน Teutsche Algebra เล่มนี้จาก 1,669 หน้า 9และหน้า 76 ; หนังสือเล่มนี้เป็นหนังสือเล่มแรกในพีชคณิตจาก 1895 หน้า 46 [48/189]

ปิดหัวข้อเล็กน้อย: เกี่ยวกับการสนทนาจริงเกี่ยวกับการแสดงออกนี้: มันไม่ควรเขียนเช่นนี้ในสถานที่แรก! คำตอบที่ถูกต้องนั้นไม่เกี่ยวข้องหากคำถามนั้นไม่ชัดเจน * * * * คลิก "ปิดเพราะมันไม่มีความชัดเจนในสิ่งที่คุณขอปุ่ม" *
และสำหรับบันทึกแม้แต่เครื่องคิดเลข Casio รุ่นต่างๆยังไม่รู้วิธีจัดการกับนิพจน์นี้อย่างถูกต้อง:
ป้อนคำอธิบายรูปภาพที่นี่

ท้าทาย:

คุณจะได้รับสองอินพุต:

  • นิพจน์ทางคณิตศาสตร์ (ใช้ได้) ที่ประกอบด้วยสัญลักษณ์เท่านั้น 0123456789+-×/÷()
  • ปี

และคุณส่งออกผลมาจากการแสดงออกทางคณิตศาสตร์ตามปี (ในกรณีที่÷มีการใช้งานแตกต่างกันเมื่อYอีaR<1918แต่จะใช้ตรงเช่นเดียวกับ/เมื่อYอีaR1918 )

กฏท้าทาย:

  • คุณสามารถสันนิษฐานได้ว่านิพจน์ทางคณิตศาสตร์นั้นถูกต้องและใช้สัญลักษณ์0123456789+-×/÷()เท่านั้น นอกจากนี้ยังหมายความว่าคุณไม่ต้องกังวลเรื่องการยกกำลัง (คุณยังได้รับอนุญาตให้ใช้สัญลักษณ์ที่แตกต่างกันสำหรับ×หรือ÷(เช่น*หรือ%) หากมันช่วยให้การเล่นกอล์ฟหรือหากภาษาของคุณรองรับ ASCII เท่านั้น)
  • คุณได้รับอนุญาตให้เพิ่มตัวเว้นวรรคลงในนิพจน์อินพุตหากสิ่งนี้ช่วยในการประเมินนิพจน์
  • I / O ยืดหยุ่นได้ อินพุตสามารถเป็นสตริงอักขระอาร์เรย์เป็นต้นปีสามารถเป็นจำนวนเต็มวันที่วัตถุสตริง ฯลฯ เอาท์พุทจะเป็นตัวเลขทศนิยม
  • คุณสามารถสันนิษฐานได้ว่าจะไม่มีแผนกใด ๆ หารด้วย 0 กรณีทดสอบ
  • คุณสามารถสมมติว่าตัวเลขในอินพุทนิพจน์นั้นจะไม่เป็นลบ (ดังนั้นคุณจะไม่ต้องจัดการกับการแยกความแตกต่างของ-สัญลักษณ์-ลบและสัญลักษณ์ลบออก) อย่างไรก็ตามเอาต์พุตยังสามารถเป็นลบได้!
  • คุณสามารถสันนิษฐานได้ว่าN(จะถูกเขียนN×(แทนเสมอ เราจะมุ่งเน้นไปที่ความขัดแย้งที่สองของสัญลักษณ์ส่วน/VS ÷ในความท้าทายนี้
  • ค่าผลลัพธ์ทศนิยมควรมีความแม่นยำอย่างน้อยสามหลักทศนิยม
  • หากอินพุตนิพจน์มีหลายค่า÷(เช่น4÷2÷2 ) ด้วยYอีaR<1918เหล่านั้นจะถูกประเมินเช่นนี้: 4÷2÷24224144 (หรือในคำว่า:หมายเลข4หารด้วยนิพจน์2÷2โดยที่นิพจน์2÷2หมายถึงเลข2ถูกหารด้วยหมายเลข2)
  • ÷×/4÷2×2÷3
  • [0000,9999]

กฎทั่วไป:

  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ
    อย่าปล่อยให้ภาษาที่ใช้รหัสกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ codegolfing พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • กฎมาตรฐานใช้สำหรับคำตอบของคุณด้วยกฎ 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

R , 68 66 ไบต์

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

ลองออนไลน์!

คาดหวังเครื่องหมายความเท่าเทียมกัน=แทน÷และ*แทน×

โค้ดใช้ประโยชน์จากโอเปอเรเตอร์ที่น่ารังเกียจบางอย่างใช้ประโยชน์จากความจริงที่ว่า=เป็นโอเปอเรเตอร์จากขวาไปซ้ายที่มีลำดับความสำคัญต่ำมาก (พฤติกรรมที่แน่นอนที่เราต้องการจากปีพ. ศ. 2461 ÷) และ R ล้นมือ ส่วนที่เหลือจะดำเนินการให้เราโดยevalอัตโนมัติ

เป็นโบนัสนี่คือวิธีการที่แน่นอนเหมือนกับที่ใช้ในไวยากรณ์ terser เวลานี้ผู้ดำเนินการส่วนพิเศษของเราคือตัวหนอน ( ~):

Julia 0.7 , 51 ไบต์

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

ลองออนไลน์!


3
`=`=`/`มันโหดร้าย! สุดยอดทางออก!
Gregor

uuugggghhh ฉันมีความคิดในบรรทัดเดียวกัน อนิจจาคุณเอาชนะฉันไปได้มากทีเดียว ลองออนไลน์
จูเซปเป้

แม้ว่าจะไม่มีคำตอบในภาษา codegolf แต่ฉันยอมรับคำตอบ Julia ของคุณสั้นที่สุดในตอนนี้ เป็นไปได้ว่าจะมีการเปลี่ยนแปลงในอนาคตแน่นอนหากมีคำตอบสั้น ๆ
Kevin Cruijssen

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)

ลองออนไลน์!

อย่างไร?

กำลังประมวลผลนิพจน์ใบไม้

ชั่วโมงอี%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()

การจัดการกับการแสดงออกที่ซ้อนกัน

ชั่วโมง

ก.

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 ดีมาก 'จากขวาไปซ้าย' ควรกดกริ่ง ... แต่ก็ไม่ได้
Arnauld

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 ในทั้งสองกรณี (ในขณะที่ควรกลับ 4 ก่อนปี 1918)
Dada

มันเป็นความจริงฉันไม่สามารถดูอีกต่อไปในขณะนี้
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)}

สนิมไม่มีอะไรที่เหมือนกับ 'eval' ดังนั้นนี่จึงค่อนข้างยาก โดยพื้นฐานแล้วนี่คือ Djisktra มาตรฐานหลาดักประเมินหลามัดด้วยการปรับเปลี่ยนเล็กน้อย ÷เป็นโอเปอเรเตอร์ที่มีลำดับความสำคัญของตัวแปร: ต่ำกว่าทุกอย่าง (แต่วงเล็บ) ในโหมด <1918 สูงกว่าทุกอย่างในโหมด> = 1918 นอกจากนี้ยังเป็น 'การเชื่อมโยงที่ถูกต้อง' (หรือซ้าย?) สำหรับ <1918 เพื่อให้ตรงกับข้อกำหนด 4 ÷ 2 ÷ 2 และการเชื่อมโยงคือ 'ปลอม' โดยการลบค่าที่มาก่อนจากนั้นในระหว่างการประเมินการดำเนินการใด ๆ มีพื้นที่สำหรับเล่นกอล์ฟมากขึ้น แต่นี่เป็นร่างที่ดีที่ฉันคิด

Ungolfed ที่ play.rust-lang.org


คุณต้องการพื้นที่ว่างมากจริงๆหรือไม่? ฉันคิดว่าส่วนใหญ่สามารถลบออกได้
ivzem

@ivzem เป็นจุดที่ดี แต่ก็ยังใหญ่กว่างูใหญ่ถึง 3 เท่า
ดอนสดใส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.