StackyMath की व्याख्या करें!


14

आपके लिए मेरी नई स्टैक आधारित भाषा को लागू करने का समय है! इसे स्टैकीमैथ कहा जाता है। यह स्टैक पर 8 संचालन और स्टैक पर संख्याओं को जोड़ने के तरीकों के साथ एक स्टैक आधारित भाषा होगी।

संचालन की सूची:

  • /: विभाजन। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है।
  • *: गुणन। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • -: घटाव। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • +: जोड़। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • ^: घातांक। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • %: मोदुलो। स्टैक के शीर्ष 2 नंबरों पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • !: कारक। स्टैक पर शीर्ष नंबर पर प्रदर्शन किया। स्टैक पर परिणाम वापस धक्का देता है
  • D: स्टैक पर शीर्ष संख्या को डुप्लिकेट करें

छद्म कोड में परिभाषित संचालन:

  • /: push(pop divided by pop)
  • *: push(pop times pop)
  • -: push(pop minus pop)
  • +: push(pop plus pop)
  • ^: push(pop to the pop)
  • %: push(pop mod pop)
  • !: push(factorial pop)
  • D: t = pop; push(t); push(t)

स्टैक पर संख्याओं को कैसे धकेलें:

स्टैक में संख्याओं को जोड़ना आसान है, बस अपने कार्यक्रम में कच्चा नंबर डालें जहां आपको इसकी आवश्यकता है। यदि आपको स्टैक पर कई नंबर लगाने की आवश्यकता है तो आप उन्हें अल्पविराम ( ,) के साथ अलग कर सकते हैं । आपके कार्यक्रम को -इनपुट में संख्याओं को संसाधित करने की आवश्यकता नहीं होगी , यदि उपयोगकर्ता चाहता है कि उन्हें एक संख्या धक्का देनी चाहिए जिसे वे नकारात्मक, शून्य और चाहते हैं -। कार्यक्रम के इनपुट में संख्या भी सकारात्मक पूर्णांकों के लिए विवश हैं।

इनपुट:

आपके प्रोग्राम को कमांड लाइन पर, या std से इनपुट लेना चाहिए। इनपुट में केवल संख्या (कोई वैज्ञानिक संकेतन या दशमलव) की ,आवश्यकता के अनुसार सीमांकित नहीं किया जाएगा , और ऊपर वर्णित संचालन।

आउटपुट:

आपके प्रोग्राम को स्टैक के शीर्ष पर नंबर प्रिंट करना चाहिए।

त्रुटि मामले:

  • यदि प्रोग्राम स्टैक को ओवर-पॉप करने की कोशिश करता है, तो आपको प्रिंट करना चाहिए StackUnderflowException!!!
  • यदि आपके पास शून्य से विभाजन है, तो प्रिंट करें DivisionByZeroException!!!
  • यदि एक संख्या जो 64-बिट से अधिक है, या तो प्रोग्राम को निष्पादित करते समय या इनपुट में एक नंबर को संसाधित करते हुए, प्रिंट करें NumberOverflowException!!!
  • यदि किसी तरह आपको स्टैक के शीर्ष पर एक ऋणात्मक संख्या मिलती है और आपको एक भाज्य करने की आवश्यकता है, तो प्रिंट करें NegativeFactorialException!!!
  • यदि आपके पास स्टैक के शीर्ष पर एक फ्लोटिंग पॉइंट नंबर है और अगला ऑपरेशन फैक्टरियल है, तो प्रिंट करें FloatingFactorialException!!!
  • यदि प्रोग्राम से बाहर निकलने पर कोई संख्या स्टैक पर नहीं है (यानी प्रोग्राम खाली था) प्रिंट EmptyProgram!!!

टिप्पणियाँ:

  • सभी त्रुटि आउटपुट को yo std या निकटतम समतुल्य मिलना चाहिए।
  • सभी नंबर 64-बिट फ्लोटिंग पॉइंट के लिए विवश हैं।

उदाहरण कार्यक्रम:

50,47*                 -> 2350
50,47/                 -> 0.94
100,8!                 -> 40320  
100D*                  -> 10000
!                      -> StackUnderflowException!!!
5,2/!                  -> FloatingFactorialException!!!  
4,3!2*/                -> 3 
654,489,48,43/5*7D+-*% -> 77.68749999999909
                       -> EmptyProgram!!!

(यदि आवश्यकता हो तो और जोड़ सकते हैं)


3
यदि यह त्रुटि के मामलों के लिए नहीं थे, तो विटसी इसे स्वाभाविक रूप से (परिवर्तित !करने के अलावा F) कर सकता था।
Addison Crump

मुझे लगा, इसीलिए मैंने उन्हें शामिल किया है।
J Atkin

3
तुम्हारा दायरा कुछ हद तक व्यापक है, हालाँकि यह तर्कपूर्ण
डिजिटल ट्रॉमा

वाह, मैं उस एक के बारे में भूल गया था। लेकिन मुझे नहीं लगता कि वे गलतियां हैं क्योंकि आपको त्रुटियों को संसाधित करना होगा और अधिक ऑपरेटरों को खान में परिभाषित किया गया है।
J Atkin

654,489,48,43/5*7D+-*%लौट जाना चाहिए 77.6875। ( 43/48*5-(7+7)होना चाहिए (7+7)-43/48*5)
user81655

जवाबों:


4

रूबी, 412 410 404 392 380 377 वर्ण

def e m,x='Exception';warn m+x+?!*3;exit;end
def o;e'StackUnderflow'if$*==[];$*.pop;end
u=->n{e'DivisionByZero'if n.infinite?;e'NumberOverflow'if n>2**64;$*<<n}
f=->n{e'NegativeFactorial'if n<0;e'FloatingFactorial'if n.to_i<n;n<2?1:f[n-1]*n}
gets.gsub(/(\d+)|([+*\/%^-])|(!)|D/){$1?u[$1.to_f]:$2?u[eval"o#{$2>?A?:**:$2}o"]:$3?u[f[o]]:u[x=o]+u[x]}
e'EmptyProgram',''if$*==[]
p o

यह नियमित रूप से सटीक संस्करण का उपयोग कर रहा है Float। नमूना कोड में परिणाम सटीक है, लेकिन संख्यात्मक अतिप्रवाह का पता लगाना सटीक नहीं है।

नमूना रन:

bash-4.3$ ruby StackyMath.rb <<< '654,489,48,43/5*7D+-*%'
77.68749999999909

रूबी, 378 377 वर्ण

def e m,x='Exception';warn m+x+?!*3;exit;end
def o;e'StackUnderflow'if$*==[];$*.pop;end
u=->n{e'NumberOverflow'if n>2**64;$*<<n}
f=->n{e'NegativeFactorial'if n<0;e'FloatingFactorial'if n.to_i<n;n<2?1:f[n-1]*n}
gets.gsub(/(\d+)|([+*\/%^-])|(!)|D/){$1?u[Rational$1]:$2?u[eval"o#{$2>?A?:**:$2}o"]:$3?u[f[o]]:u[x=o]+u[x]}rescue e'DivisionByZero'
e'EmptyProgram',''if$*==[]
p o.to_f

यह उच्च परिशुद्धता संस्करण का उपयोग कर रहा है Rational। परिणाम सटीकता हमेशा नमूना कोड के समान नहीं होती है, लेकिन संख्यात्मक अतिप्रवाह का पता लगाना सटीक होता है।

नमूना रन:

bash-4.3$ ruby StackyMath-hi.rb <<< '654,489,48,43/5*7D+-*%'
77.6875

3

जावास्क्रिप्ट (ईएस 6), 430 बाइट्स

बदलकर ES7 के साथ 422 बाइट्स Math.pow(2,2)के लिए2**2

e=m=>{throw alert(m)};u=prompt();u?alert(eval('u.match(/\\d+|[^,]/g).map(o=>s.push(t=o=="/"?(b=p(a=2))?a/b:e`DivisionByZero43*"?2*23-"?2-23+"?2+23%"?2%23^"?Math.pow(2,2)3D"?s.push(r=2)&&r3!"?eval("for(r=i=2;i<0?e`Negative54:i%1?e`Floating54:--i;)r*=i;r"):+o)&&t==Infinity&&e`NumberOverflow4,s=[],p=_=>s.length?s.pop():e`StackUnderflow4);t'.replace(/[2-5]/g,x=>[,,'p()',':o=="','Exception!!!`','Factorial'][x]))):e`EmptyProgram!!!`

व्याख्या

evalकुछ सामान्य वाक्यांशों को बदलने के लिए उपयोग करता है। Ungolfed और इसके बिना evalऐसा दिखता है:

e=m=>{throw alert(m)};                           // e = throw error, alert displays
                                                 //     message, throw stops execution
u=prompt();                                      // u = received input
u?alert(                                         // display the result
  u.match(/\d+|[^,]/g)                           // get array of numbers and operators
    .map(o=>                                     // iterate over operators
      s.push(t=                                  // t = last pushed value

        // Execute operator
        o=="/"?(b=p(a=p()))?a/b:                 // make sure argument B is not 0
          e`DivisionByZeroException!!!`:
        o=="*"?p()*p():
        o=="-"?p()-p():
        o=="+"?p()+p():
        o=="%"?p()%p():
        o=="^"?Math.pow(p(),p()):
        o=="D"?s.push(r=p())&&r:
        o=="!"?eval("                            // eval to enable for loop in ternary
          for(                                   // no factorial in JS so do this manually
            r=i=p();
            i<0?e`NegativeFactorialException!!!` // check for errors
              :i%1?
                e`FloatingFactorialException!!!`
                :--i;
          )
            r*=i;
          r"):                                   // return r
        +o                                       // if not an operator cast as a number
      )&&t==Infinity&&                           // JS turns anything over 64 bit float
        e`NumberOverflowException!!!`,           //     max value into Infinity
      s=[],                                      // s = stack array
      p=_=>s.length?s.pop():                     // p = check stack then pop
        e`StackUnderflowException!!!`
    )&&t                                         // return top stack element
  ):e`EmptyProgram!!!`                           // error if input length is 0

आप ES7 को अपग्रेड करना चाहते हैं, तो आप इस्तेमाल कर सकते हैं ES7 घातांक ऑपरेटर बदलने के लिए Math.pow(p(),p())के साथ p()**p()
usandfriends

1
@usandfriends मैं इसके बारे में सोच रहा था, लेकिन इसका मतलब था कि यह मेरे ब्राउज़र में काम नहीं करेगा इसलिए मैंने इसे छोड़ दिया। : P मैं यह कहते हुए एक नोट जोड़ूंगा।
user81655

1

ग्रूवी, 718 बाइट्स। फोर!

हो सकता है कि मेरी इम्पोर्टेड गोल्फ भी पोस्ट की जाए। मिलिए मेरे कोड की बड़ी दीवार से:

g='Exception!!!'
a={System.err.print(it);System.exit(1)}
b=new Stack()
c={b.push(it)}
v=2d**64d
d={b.pop()}
e={if(b.size()<it)a('StackUnderflow'+g)}
f={a('NumberOverflow'+g)}
h={e(2)
c(Eval.xy(d(),d(),"x$it y"))
if(b.peek()>v)f()}
k={i->if(i<0)a('NegativeFactorial'+g)
if(Math.abs(i-(i as long))>1E-6)a('FloatingFactorial'+g)
(2..i).inject{x,y->(v/x<y)?f():x*y}}
l=['/':{e(2)
m=d()
n=d()
if(n==0)a('DivisionByZero'+g)
c(m/n)},'!':{e(1)
c(k(d()))},'D':{e(1)
c(b.peek())}]
System.in.newReader().readLine().findAll(~/\d+|[^,]/).each{x->if(x.matches(/\d+/))try{c(x as double)}catch(Exception e){f()}
else if("+-*%^".contains(x))h(x.replace('^','**'))
else l[x]()}
if(b){o=d()
if(Double.isInfinite(o))f()
println o}else a('EmptyProgram!!!')

Ungolfed:

error = {System.err.print(it);System.exit(1)}

stack = new Stack()
maxVal = 2d**64d

push = {stack.push(it)}
pop = {stack.pop()}

checkAtLeast = {if (stack.size() < it) error('StackUnderflow'+exception)}
numberOverflow = {error('NumberOverflow'+exception)}

exception = 'Exception!!!'

def dArgOp(i) {
    checkAtLeast(2)
    push(Eval.xy(pop(), pop(), "x$i y"))
    if(stack.peek() > maxVal) numberOverflow
}

factorial = {i->
    if (i < 0)
        error('NegativeFactorial'+exception)
    if (Math.abs(i - (i as long)) > 1E-6)
        error('FloatingFactorial'+exception)
    (2..i).inject {acc, it ->
        (maxVal/acc < it)?numberOverflow():acc*it
    }
}

ops = [
'/' : {
    checkAtLeast(2)
    first = pop()
    second = pop()
    if (second == 0)
        error('DivisionByZero'+exception)
    push(first / second)
},
'!' : {
    checkAtLeast(1)
    push(factorial(pop()))
},
'D' : {
    checkAtLeast(1)
    push(stack.peek())
}]

input = System.in.newReader().readLine()
tokens = input.findAll(~/\d+|[^,]/)

tokens.each {
    print "current token: $it  \t stack before eval: $stack "
    if (it.matches(/\d+/))
        try {
            push(it as double)
        } catch (Exception e) {
            numberOverflow()
        }

    else if ("+-*%^".contains(it))
        dArgOp(it.replace('^','**'))
    else
        ops[it]()
    println "result: ${stack.peek()}"
}

if (stack) {
    top = pop()
    if (Double.isInfinite(top))
        numberOverflow()
    println top
} else
    error('EmptyProgram!!!')

संपादित 1: save ~ 15 बाइट्स @Doorknob के लिए धन्यवाद
2 संपादित करें: ड्रॉप ~ 130 बाइट्स कुछ और ट्रिक्स के साथ


मैं ग्रूवी को नहीं जानता, लेकिन आपको लगता है कि बहुत सारे अनावश्यक व्हाट्सएप हैं। उदाहरण के लिए, चारों ओर ऑपरेटरों, के बाद for/ if, आदि
दरवाज़े

व्हाट्स, बस व्हाट्सएप को हटाने के लिए कई और स्थानों पर ध्यान दिया गया। पारितोषिक के लिए धन्यवाद।
J Atkin

आप उपयोग कर सकते हैं System.in.textके बजाय System.in.newReader().readLine()
एक स्पेगेटो

ज़रुरी नहीं। .textलालची है और जब तक पाठक में डेटा है, यह वापस नहीं आएगा।
जे एटकिन

सही है, लेकिन यह कोड-गोल्फ है। अगर लोगों को अपने इनपुट के बाद Control-D टाइप करना है तो यह कोई बड़ी बात नहीं है।
एक स्पेगेटो

1

कैंडी , 298 348 392 बाइट्स

यद्यपि कैंडी स्टैक आधारित है, मुझे यकीन नहीं है कि वास्तव में मदद की है ...

&{|"EmptyProgram!!!\n"(;).}(=bYZay0=zx4k"!%*+,-/D^"(iYe{Z=x})aYb=z=ya=X{Y{cZ0=yza}b212202221(i=ZXe{y})a0=zcY0j{XjZ{|D1b#64R(=c2*)c>{b"NumberOverFlow"(;)i}}|i}aZ{(=)"Exception!!!\n"(;).}0=yz|A#48-Z#10*+=z1=y})c?(=).@0&<{1|b"StackUnderflow"(;)c0}.@1~ALe{A0<{b"Negative"(;)i|1bAR(=cA*)}|b"Floating"(;)i}Z{b"Factorial"(;)}.@2W%.@3*.@4+@5.@6W-.@7WD{/|b"DivisionByZero"(;)i}.@8~A.@9=xK=y=1bA_(cX*).

थोड़ा सा स्वरूपित संरचना का एक सा पता चलता है:

&{|"EmptyProgram!!!\n"(;).}
(=bYZay0=zx4k
  "!%*+,-/D^"
  (iYe{Z=x})
  aYb=z=ya=X
  {
    Y{cZ0=yza}b
    212202221(i=ZXe{y})
    a0=zcY0j
    {XjZ{|D1b#64R(=c2*)c>{b"NumberOverFlow"(;)i}}|i}
    aZ{(=)"Exception!!!\n"(;).}
    0=yz|A#48-Z#10*+=z1=y
  }
)c?(=).
@0&<{1|b"StackUnderflow"(;)c0}.
@1~ALe{A0<{b"Negative"(;)i|1bAR(=cA*)}|b"Floating"(;)i}Z{"Factorial"(;)}.
@2W%.@3*.@4+@5.@6W-.@7WD{/|"DivisionByZero"(;)i}.@8~A.@9=xK=y=1bA_(cX*).

वास्तविक गणित अंतिम दो लाइनों पर होता है। यह तीसरी लाइन पर एक जंप टेबल द्वारा संचालित है।


डांग, मैं देख रहा हूं कि मुझे डिवीजनबीजेरो, नेगेटिवफैक्टरी, और ओवरफ्लो याद आया। मैं सिर्फ परीक्षा के मामलों को देख रहा था!
डेल जॉनसन

वाह, यह अच्छा है। मुझे बस कैंडी देखने की आवश्यकता हो सकती है।
J Atkin

मैं अभी भी काम कर रहा हूं कि कैसे अतिप्रवाह को परिभाषित किया जाए
डेल जॉन्सन

वास्तव में मुझे अपने उत्तर में यही समस्या थी। मेरे उत्तर के नीचे टिप्पणियाँ देखें।
जे एटकिन

अब ओवरफ्लो तय कर दिया। मैंने रूबी के रूप में एक ही दृष्टिकोण का उपयोग किया, जो कि प्रत्येक ऑपरेशन के अंत में 2 ^ 64 की तुलना में है।
डेल जॉनसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.