Dames, làm một số toán học!


19

Thứ tự các phép toán, PEMDAS, là một quy tắc cơ bản trong toán học cho chúng ta biết nên thực hiện các phép toán thứ tự nào:

"Dấu ngoặc đơn, số mũ, phép nhân và phép chia, phép cộng và phép trừ"

Vấn đề là, PEMDAS không linh hoạt lắm! Điều gì nếu bạn muốn làm điều đó theo thứ tự khác? Chúng tôi sẽ không gây rối với dấu ngoặc đơn, vì vậy chúng tôi giữ chúng ở vị trí của chúng (đầu tiên).

Tạo một chương trình có hai đối số:

  • Một chuỗi, cho biết thứ tự các hoạt động nên theo. Một số ví dụ là "DAMES", "SAD, ME", "ME SAD", "MEADS". Có, dấu cách và dấu phẩy là OK, vì nó làm cho thứ tự dễ nhớ hơn.
    • Theo đề xuất trong trò chuyện: Không gian hỗ trợ và dấu phẩy hiện là tùy chọn.
    • Nếu một trong các chữ cái bị thiếu hoặc nếu có thêm các chữ cái không nên ở đó, bạn có thể xem xét đầu vào không hợp lệ và xử lý nó theo cách bạn muốn.
  • Một chuỗi hoặc một biểu thức có chứa biểu thức cần được ước tính.

Trả về kết quả của biểu thức dưới dạng số thập phân hoặc số nguyên. Nếu câu trả lời không phải là số nguyên, nó phải được trả về dưới dạng số thập phân.

Quy tắc:

  • Bạn có thể kết hợp hai đối số đầu vào thành một, nếu ngôn ngữ của bạn dễ dàng hơn.
  • Nó không phải là một chuỗi, nhưng nó phải có các chữ cái. Bạn không thể thay thế Bổ sung bằng 1, Phân chia bằng 2, v.v.
  • Bạn có thể chọn đầu vào nào là đầu tiên.
  • Biểu thức được đánh giá từ phải sang trái sang phải. (Thay đổi quy tắc. Bất kỳ bài đăng nào trong 12 giờ đầu tiên có cách này đều được chấp nhận).
  • Các hoạt động sử dụng các ký hiệu : ( ) ^ * / + -. Chẳng hạn, bạn không thể sử dụng ¤thay vì +bổ sung.
  • Dấu cách trong biểu thức nhập không hợp lệ làm đầu vào
  • Unary +/- không hợp lệ làm đầu vào nếu nó trực tiếp theo sau + hoặc -. Coi 3+-2như là đầu vào không hợp lệ. Nó có thể được xử lý theo cách bạn muốn (không phải tạo ra lỗi). Nếu +hoặc -theo bất kỳ toán tử nào khác ngoài cộng hoặc trừ, thì nó được xử lý theo cách thông thường : 3*-3 = -9,sin(-2)=-0.909
  • Chương trình phải tuân thủ nghiêm ngặt các chữ cái, vì vậy "EMDAS", 1-3+4 => -6, và "EMDSA", 1-3+4 => 2.

Ví dụ:

Input:   "EMDAS", "3+6*2/4-1"   // -> 3+12/4-1 -> 3+3-1 -> 6-1 -> 5
Output:  5

Input:   "DAMES", "3+6*2/4-1"   // -> 3+6*0.5-1 -> 9*0.5-1 -> 4.5-1 -> 3.5
Output:  3.5

Input:   "SAD, ME", "3+6*2/4-1"  // -> 3+6*2/3 -> 9*2/3 -> 9*0.66667 -> 6   
Output:  6

Input:   "ME ADS", "3+5^4/2-3*2 // -> 3+5^4/2-6 -> 3+625/2-6 -> 628/2-6 -> 314-6 -> 308
Output:  308

Input:   "AM EDS", "4*3-sin(0.5^2)*3+1" // -> 4*3-sin(0.5^2)*4 -> 12-sin(0.5^2)*4 -> 4*3-(4*sin(0.5^2)) -> 12-(4*sin(0.5^2)) -> 12-(4*sin(0.25)) -> 12-(4*0.24740) -> 12-0.98961 -> 11.01038
Output:  11.01038

Input:   "DAMES", "4-5-6"   // -> (4-5)-6 -> = -7  
Output:  -7                  // NOT: -> 4-(5-6) -> 4-(-1) -> 5

Lưu ý, các dấu ngoặc đơn được thêm vào để chỉ ra rằng phép nhân 4*sin(0.5^2)được đánh giá trước khi lũy thừa.

Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


2
Nó hoàn toàn không giống nhau chút nào nhưng thử thách này là về việc thay đổi thứ tự hoạt động khác và là nguồn cảm hứng khiến tôi thích ý tưởng làm một việc tương tự. Tôi nghĩ rằng câu trả lời của Haskell có thể được thực hiện lại để trả lời câu hỏi này có lẽ ... Không chắc chắn nếu một bản sao nghiêm ngặt, tôi khá thích ý tưởng thực hiện thử thách này mà không có khả năng thay đổi trực tiếp các nhà khai thác!
Dom Hastings

2
Phần thưởng cho các hàm bị loại bỏ, nhưng vẫn có sin () trong các ví dụ.
edc65

Hơi tệ hơn so với thử thách đã nói ở trên, và tôi sẽ không tranh luận nó là bản sao (mặc dù một liên kết đến bản gốc sẽ được đánh giá cao). Tuy nhiên, thật đơn giản khi mọi người thấy giám đốc độc ác của The 2560 không ai khác chính là @Stewie Griffin. Tôi phải nói rằng, tôi không ngạc nhiên.
Jake

Ở Anh, chúng tôi thường được dạy nó như BODMAShoặc BIDMASở trường. B= Chân đế, Ohoặc I= Đặt hàng hoặc Chỉ số.
BadHorsie

pcần thiết không? Nó không có trong các ví dụ
ev3commander

Câu trả lời:


7

JavaScript (ES6) 349 353 387 400

... có lẽ vẫn chơi được

Trình phân tích cú pháp cũ này của tôi đôi khi có ích - (đã được sử dụng trong 2 thử thách khác)

E=
(d,x,W=[],Q=['_'],h={'(':1,_:8,')':7},z=1,C=n=>{for(;h[q=Q.pop()]<=h[n];W.push(q=='^'?Math.pow(a,b):eval(`a${q}b`)))a=W.pop(b=W.pop());Q.push(q,n)})=>([...d].map(l=>h[l='+-/*^'['ASDME'.search(l)]]=(d+=!!l),d=1),(x+')').replace(/\D|\d+/g,t=>(u=~~h[t])-1?u-7?u?z&&t=='-'?z=-z:C(t,z=1):(W.push(z*t),z=0):Q.pop(Q.pop(C(t),z=0)):z=!!Q.push('_')),W.pop())

// TEST
console.log=(...x)=>O.innerHTML+=x.join` `+'\n'

console.log(E('MDASE','3+4*5^2'))
console.log(E("EMDAS", "3+6*2/4-1")) // 5
console.log(E("DAMES", "3+6*2/4-1")) //3.5
console.log(E("SAD, ME", "3+6*2/4-1")) // 6
console.log(E("ME ADS", "3+5^4/2-3*2")) // 308
console.log(E("AM EDS", "4*3-sin(0.5^2)*3+1")) // 11.01038 sin not supported
console.log(E("DAMES", "4-5-6")) // -7

// MORE READABLE
U=(d,x,W=[],Q=['_'],h={'(':1,_:8,')':7},z=1,
  C=n=>{
    for(;h[q=Q.pop()]<=h[n];
        W.push(q=='^'?Math.pow(a,b):eval(`a${q}b`)))
      a=W.pop(b=W.pop());
    Q.push(q,n)
  }
)=>(
  [...d].map(l=>h[l='+-/*^'['ASDME'.search(l)]]=(d+=!!l),d=1),
  (x+')').replace(/\D|\d+/g,t=> 
     (u=~~h[t])-1
       ?u-7
         ?u
           ?z&&t=='-'?z=-z:C(t,z=1)
           :(W.push(z*t),z=0)
         :Q.pop(Q.pop(C(t),z=0))
       :(Q.push('_'),z=1)
  ),
  W.pop()
)
<pre id=O></pre>

Bị đánh cắp

Evaluate=(oprec,expr)=>
{
  var tokens = expr.match(/\D|\d+/g).concat(')')
  var t,a,b,v, SignV
  var vstack=[]
  var ostack=['_']
  var op={ '(':8, _: 1, ')':2}
  oprec.match(/\w/g).map((l,p)=>op['+-/*^'['ASDME'.search(l)]]=7-p)
  var OPush=o=>ostack.push(o)
  var OPop=_=>ostack.pop()
  var VPush=v=>vstack.push(v)
  var VPop=v=>vstack.pop()

  var Scan=i=>
  {
    SignV = 1
    for (; t=tokens[i++]; )
    {
      if (t == '(')  
      {
        OPush('_')
        SignV = 1
      }
      else if (t == ')')
      {
        CalcOp(t);
        OPop();
        OPop();
        SignV = 0
      }
      else if (op[t])
      {
        if (SignV && t=='-')
          SignV = -SignV
        else
          CalcOp(t), SignV = 1
      }  
      else
      {
        VPush(SignV*t)
        SignV=0
      }
    }
  }
  var CalcOp=nop=>
  {
    for (; op[po = OPop()] >= op[nop];)
      b=VPop(), a=VPop(), CalcV(a,b,po);
    OPush(po), OPush(nop);
  }
  var CalcV=(a,b,o)=>
  {
//    console.log('CV',a,b,o)
    if (o=='+')
      a+=b
    if (o=='-')
      a-=b
    if (o=='*')
      a*=b
    if (o=='/')
      a/=b
    if (o=='^')
      a=Math.pow(a,b)
    VPush(a)
  }
  Scan(0)

  return VPop()
}

console.log=(...x)=>O.innerHTML+=x.join` `+'\n'

console.log(Evaluate('MDASE','3+4*5^2'))
console.log(Evaluate('EMDAS','3+6*2/4-1')) // 5
console.log(Evaluate("DAMES", "3+6*2/4-1")) //3.5
console.log(Evaluate("SAD, ME", "3+6*2/4-1")) // 6
console.log(Evaluate("ME ADS", "3+5^4/2-3*2")) // 308
console.log(Evaluate("AM EDS", "4*3-sin(0.5^2)*3+1")) // 11.01038 sin not supported
console.log(Evaluate("DAMES", "4-5-6")) // -7
<pre id=O></pre>


Tôi nghĩ rằng bạn có thể loại bỏ không gian trong (t=>t=='('?(z=1, Q.push('_')), cùng với tất cả các dòng mới.
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ làm việc trên nó. Cảm ơn
edc65

Tôi nghĩ bạn có thể thay đổi Math.pow(a,b)thànha**b
Kritixi Lithos

@KritixiLithos có nhưng nó sẽ không còn là ES6 nữa
edc65

6

R 3.3.2: 209 196 187 177 byte

Ý tưởng là "lạm dụng" các toán tử phi số học <, &, |, ~ ,? trong đó chúng ta biết mức độ ưu tiên (xem ?Syntaxtrong R - nhưng trước phần ghi đè;)) và ghi đè chúng bằng các toán tử số học đã cho. Các ánh xạ là theo thứ tự hoạt động mong muốn.

Dấu cách và dấu phẩy trong đầu vào không được hỗ trợ.

Phiên bản chơi gôn

f=function(a,b){s=substr;l=list(E='^',M='*',D='/',A='+',S='-');q="<&|~?";for(i in 1:5){x=s(q,i,i);y=l[[s(a,i,i)]];assign(x,.Primitive(y));b=gsub(y,x,b,,,T)};eval(parse(text=b))}

Ungolfed và bình luận:

f = function(a,b) {
  s = substr
  # All arithmetic operators
  l = list(E = '^', M = '*', D = '/', A = '+', S = '-')
  # Some non-arithmetic R operators in descending precedence
  q = "<&|~?"
  for (i in 1:5) {
    # The substituted symbol
    x = s(q, i, i)
    # The original operator which has to be substituted
    y = l[[s(a, i, i)]]
    # Substitute the operator for the R interpreter
    assign(x, .Primitive(y))
    # Substitute the operator in the input string
    b = gsub(y, x, b, , , T)
  }
  # Parse and evaluate
  eval(parse(text = b))
}

Ví dụ:

> f("EMDAS", "3+6*2/4-1")
[1] 5
> f("DAMES", "3+6*2/4-1")
[1] 3.5
> f("SADME", "3+6*2/4-1")
[1] 6
> f("MEADS", "3+5^4/2-3*2")
[1] 308
> f("AMEDS", "4*3-sin(0.5^2)*3+1")
[1] 11.01038
> f("DAMES", "4-5-6")
[1] -7
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.