Dames, biraz matematik yap!


19

İşlem sırası PEMDAS, hangi sipariş işlemlerinin yapılması gerektiğini bize bildiren matematikte temel bir kuraldır:

"Parantez, Üsler, Çarpma ve Bölme ve Toplama ve Çıkarma"

Sorun şu ki, PEMDAŞ çok yönlü değil! Ya başka bir sırayla yapmak isteseydiniz? Parantezlerle uğraşmayacağız, bu yüzden onları oldukları yerde tutuyoruz (ilk olarak).

İki argüman alan bir program oluşturun:

  • İşlemlerin hangi sırayı izlemesi gerektiğini söyleyen bir dize. Bazı örnekler şunlardır "DAMES", "SAD, ME", "ME SAD", "MEADS". Evet, boşlukların ve virgüllerin kullanılması, siparişin hatırlanmasını kolaylaştırdığı için uygundur.
    • Sohbetteki önerileri takip edin: Destek alanları ve virgüller artık isteğe bağlıdır.
    • Harflerden biri eksikse veya orada olmaması gereken ek harfler varsa, girişi geçersiz sayıp istediğiniz gibi davranabilirsiniz.
  • Değerlendirilmesi gereken ifadeyi içeren bir dize veya ifade.

İfadenin sonucunu ondalık sayı veya tamsayı olarak döndürür. Yanıt bir tamsayı değilse, ondalık sayı olarak döndürülmelidir.

Kurallar:

  • Eğer dilinizde daha kolaysa, iki giriş argümanını bir araya getirmeniz uygundur.
  • Bir dize olmak zorunda değil, ama harfleri olmalı. Eklemeyi 1, Bölüm 2'yi vb. İle değiştiremezsiniz.
  • Hangi girişin ilk olacağını seçebilirsiniz.
  • İfade sağdan sola soldan sağa değerlendirilir . (Kural değişikliği. Bunun tersi olan ilk 12 saat içinde gönderilen posterler kabul edilir).
  • Operasyon semboller kullanılmıştır: ( ) ^ * / + -. Örneğin, kullanamaz ¤yerine +eklenmesi için.
  • Girdi ifadesindeki boşluklar girdi olarak geçerli değil
  • Tekli +/- doğrudan + veya - değerini takip ediyorsa giriş olarak geçerli değildir. 3+-2Geçersiz girdi olarak düşünün . İstediğiniz gibi tedavi edilebilir (hata üretmek zorunda değildir). Eğer +ya -artı ya da eksi dışında herhangi operatörü izler, her zamanki şekilde tedavi oluyor: 3*-3 = -9,sin(-2)=-0.909
  • Program harfleri harfiyen izlemelidir, yani "EMDAS", 1-3+4 => -6, ve "EMDSA", 1-3+4 => 2.

Örnekler:

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

Burada, çarpma 4*sin(0.5^2)işleminin üslemeden önce değerlendirildiğini göstermek için parantez eklenmiştir .

Bu kod golf, yani bayt en kısa kod kazanmak.


2
Tam olarak aynı değil ama bu zorluk başka bir operasyon sırasına geçmekle ilgili ve beni benzer bir şey yapma fikri gibi yapan ilham kaynağı oldu. Haskell cevabı belki de bu soruyu cevaplamak için yeniden çalışılabilir düşünüyorum ... Kesin bir kopya olup olmadığından emin değilim, operatörleri doğrudan değiştirme yeteneği olmadan bu zorluğu yapma fikrini çok seviyorum!
Dom Hastings

2
İşlevler için bonus kaldırıldı, ancak örneklerde hala sin () var.
edc65

Bahsedilen meydan okumadan biraz daha kötü ve bunu orijinal olarak tartışmayacağım (orijinaline bir bağlantı takdir edilecektir). Ancak, herkesin The 2560'ın kötü yönetmeni @Stewie Griffin'den başka bir şey olmadığını görmek açıktır. Söylemeliyim ki, şaşırmadım.
Jake

İngiltere'de bunu genellikle okulda BODMASveya BIDMASokulda öğretiriz. B= Parantez Oveya I= Sıra veya Endeksler.
BadHorsie

Is pgerekli? Örneklerde değil
ev3commander

Yanıtlar:


7

JavaScript (ES6) 349353387 400

... belki hala golf oynayabilir

Bu eski ayrıştırıcım bazen kullanışlı oluyor - (diğer 2 zorlukta zaten kullanılıyor)

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>

Ungolfed

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>


Sanırım (t=>t=='('?(z=1, Q.push('_'))tüm yeni satırlarla birlikte içindeki alanı kaldırabilirsiniz .
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ üzerinde çalışıyor. Teşekkürler
edc65

Ben değiştirebileceğiniz düşünmek Math.pow(a,b)içina**b
Kritixi Lithos

@KritixiLithos evet ama artık ES6 olmaz
edc65

6

R 3.3.2: 209 196 187 177 bayt

Fikir, aritmetik olmayan operatörleri <, &, |, ~,? burada önceliği biliyoruz (bkz ?Syntax. R - fakat geçersiz kılmadan önce;)) ve verilen aritmetik işleçlerle geçersiz kılınır. Eşleme istenen işlem sırasına göre yapılır.

Girişteki Spaces ve virgül edilir değil destekledi.

Golf versiyonu

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 ve yorum yaptı:

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

Örnekler:

> 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.