Dames, do some math!
JavaScript (ES6) 349 353 387 400
... maybe still golfable
This old parser of mine sometimes comes in handy - (already used in other 2 challenges)
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>
R 3.3.2: 209 196 187 177 bytes
The idea is to "misuse" the non-arithmetic operators <, &, |, ~, ? where we know the precedence (see ?Syntax
in R - but before the override ;)) and overriding them with the given arithmetic operators. The mapping is according to the desired order of operations.
Spaces and commas in the input are not supported.
Golfed version
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 and commented:
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))
}
Examples:
> 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