অ্যাডভান্সড ক্যালকুলেটর


28

আপনাকে অবশ্যই এমন একটি প্রোগ্রাম লিখতে হবে যা একটি স্ট্রিংকে মূল্যায়ন করে যা একটি উন্নত ক্যালকুলেটরে প্রবেশ করানো হবে।

প্রোগ্রামটি অবশ্যই স্টিডিন ব্যবহার করে ইনপুট গ্রহণ করবে এবং সঠিক উত্তরটি আউটপুট করবে। যে ভাষাগুলির স্ট্যান্ডিন গ্রহণ করার জন্য কোনও ফাংশন নেই, তাদের পক্ষে আপনি কার্যগুলি গ্রহণ করতে readLineএবং printএই কাজগুলি পরিচালনা করতে পারেন ।

প্রয়োজনীয়তা:

  • কোনও ধরণের "eval" ফাংশন ব্যবহার করে না
  • ভাসমান পয়েন্ট এবং negativeণাত্মক সংখ্যাগুলি পরিচালনা করতে পারে
  • কমপক্ষে +, -, *, /, এবং ^ অপারেটরদের সমর্থন করে
  • স্বাভাবিক ক্রমটিকে ওভাররাইড করার জন্য বন্ধনী এবং প্রথম বন্ধনী সমর্থন করে
  • অপারেটর এবং সংখ্যাগুলির মধ্যে এক বা একাধিক স্পেস যুক্ত ইনপুট পরিচালনা করতে পারে
  • ক্রিয়াকলাপের মান ক্রম ব্যবহার করে ইনপুটটি মূল্যায়ন করে

পরীক্ষার মামলা

ইনপুট

10 - 3 + 2

আউটপুট

9


ইনপুট

8 + 6 / 3 - 7 + -5 / 2.5

আউটপুট

1


ইনপুট

4 + [ ( -3 + 5 ) * 3.5 ] ^ 2 - 12

আউটপুট

41

1
আউটপুটযুক্ত সংখ্যাগুলির .0শেষে যদি তারা পূর্ণসংখ্যা হয় তবে এটি ঠিক হয় ? এছাড়াও: ক্যালকুলেটরটি কতটা সঠিক হতে হবে (ভাসমান পয়েন্ট যথার্থতা এবং এই জাতীয় সম্পর্কে)?
sepp2k

1
আউটপুট শেষে .0শেষ হতে পারে। আমি নির্ভুলতা সম্পর্কে খুব বেশি নিশ্চিত নই, তবে আরও ভাল।
কেভিন ব্রাউন

1
স্ট্যাক ওভারফ্লো সংস্করণটি ছিল গাণিতিক এক্সপ্রেশন মূল্যায়নকারী (পূর্ণ PEMDAS) । যদিও এর উত্তরটির অনেকগুলিই লাইন গণনা করছে (?!?)। এখনও সি তে বেশ কয়েকটি কমপ্যাক্ট উত্তর রয়েছে।
dmckee

পিএন / আরপিএন ক্যালকুলেটরগুলির জন্য বোনাস?
মতিন উলহাক

উত্তর:


8

সি ++, 640 583

string k="[]()+-*/^";stack<double> m;stack<char> n;
#define C(o,x,y) ('^'==o?x<y:x<=y)
#define Q(a) double a=m.top();m.pop();
#define R(o) {Q(b)Q(a)m.push(o=='+'?a+b:o=='-'?a-b:o=='*'?a*b:o=='/'?a/b:o=='^'?pow(a,b):0);n.pop();}
while(!cin.eof()){string s;getline(cin,s,' ');if(s.empty())continue;if('\n'==*--s.end())s.erase(--s.end());(s.size()==1&&s.npos!=k.find(s[0]))?({char c=s[0]=='['?'(':s[0]==']'?')':s[0];while(!n.empty()&&'('!= c&&C(c,k.find(c),k.find(n.top())))R(n.top());')'==c?n.pop():n.push(c);}):m.push(strtod(s.c_str(),0));}while(!n.empty())R(n.top());cout<<m.top()<<endl;

সংভৃত

string k="[]()+-*/^";
stack<double> m;
stack<char> n;
#define C(o,x,y) ('^'==o?x<y:x<=y)
#define Q(a) double a=m.top();m.pop();
#define R(o) {Q(b)Q(a)m.push(o=='+'?a+b:o=='-'?a-b:o=='*'?a*b:o=='/'?a/b:o=='^'?pow(a,b):0);n.pop();}
while(!cin.eof())
{
    string s;
    getline(cin,s,' ');
    if(s.empty())continue;
    if('\n'==*--s.end())s.erase(--s.end());
    (s.size()==1&&s.npos!=k.find(s[0]))?({
        char c=s[0]=='['?'(':s[0]==']'?')':s[0];
        while(!n.empty()&&'('!= c&&C(c,k.find(c),k.find(n.top())))
            R(n.top());
        ')'==c?n.pop():n.push(c);
    }):m.push(strtod(s.c_str(),0));
}
while(!n.empty())
    R(n.top());
cout<<m.top()<<endl;

আমার প্রথম কোড গল্ফ, তাই মন্তব্য ও সমালোচনার প্রত্যাশায়!


এক্সপেনসিটিশন অপারেটরের ডান-অ্যাসোসিয়েটিভিটি পরিচালনা করে, যা জেবির পার্ল সমাধান মনে হয় না solution
drspod

সমস্যার বিবৃতি বা লিঙ্কযুক্ত উইকিপিডিয়া পৃষ্ঠাগুলির উল্লেখ তাত্পর্য হিসাবে ডান-সহযোগী হতে হবে না। তদ্ব্যতীত, উইকিপিডিয়া পৃষ্ঠাটি স্পষ্টভাবে বলেছে যে দুটি উপায় বাণিজ্যিক ক্যালকুলেটরগুলিতে পাওয়া যায়।
জেবি

1
+1 চমত্কারভাবে গল্ফ হয়েছে, তবে ... কেবল বাদ পড়া অন্তর্ভুক্ত রয়েছে using namespace stdএবং একটি মূল ফাংশন সত্যিই ঠিক নয়, তাই না?
ঘড়ির

2

পিএইচপি - 394 354 312 টি অক্ষর

<?=e(!$s=preg_split('#\s+#',`cat`,-1,1),$s);function e($P,&$s){$S='array_shift';if(($a=$S($s))=='('|$a=='['){$a=e(0,$s);$S($s);}while($s&&($p=strpos(' +-*/^',$o=$s[0]))&&$p>=$P){$b=e($p+($S($s)!='^'),$s);if($o=='+')$a+=$b;if($o=='-')$a-=$b;if($o=='*')$a*=$b;if($o=='/')$a/=$b;if($o=='^')$a=pow($a,$b);}return$a;}

ইন্ডেন্টযুক্ত:

<?
preg_match_all('#\d+(\.\d+)?|\S#',`cat`,$m);
$s=$m[0];
function e($P) {
        global $s;
        if (strpos(" ([",$s[0])){
                array_shift($s);
                $a=e(0);
                array_shift($s);
        } else {
                $a=array_shift($s);
                if ($a=='-')$a.=array_shift($s);
        }
        while ($s && ($p=strpos(' +-*/^',$o=$s[0])) && $p >= $P) {
                array_shift($s);
                $b = e($p+($o!='^'));
                switch($o){
                case'+':$a+=$b;break;
                case'-':$a-=$b;break;
                case'*':$a*=$b;break;
                case'/':$a/=$b;break;
                case'^':$a=pow($a,$b);
                }
        }
        return $a;
}
echo e(0);

2

পোস্টস্ক্রিপ্ট, 446

এটি শান্টিং ইয়ার্ড অ্যালগরিদম ব্যবহার করে।

[/*[/p
2/e{mul}>>/d[/p
2/e{div}>>/+[/p
1/e{add}>>/-[/p
1/e{sub}>>/o[/p
9/e{}>>/c[/p
-1/e{}>>/^[/p
3/e{exp}>>/p
0>>begin/s(%stdin)(r)file 999 string readline pop def
0 1 s length 1 sub{s exch[0 1 255{}for]dup[(\(o)([o)(\)c)(]c)(/d)]{{}forall
put dup}forall
pop
3 copy pop
get
get
put}for{s token not{exit}if
exch/s exch store{cvr}stopped{load
dup/p get
p
le{currentdict end
exch begin/e get exec}{begin}ifelse}if}loop{{e end}stopped{exit}if}loop
=

আন-গল্ফড এবং মন্তব্য করেছে:

% We associate the operators with their precedence /p and the executed commend /e
[
  (*)[/p  2 /e{mul}>>
  (d)[/p  2 /e{div}>> % This is division
  (+)[/p  1 /e{add}>>
  (-)[/p  1 /e{sub}>>
  (o)[/p  9 /e{   }>> % This is open bracket
  (c)[/p -1 /e{   }>> % This is close bracket
  (^)[/p  3 /e{exp}>>
  /p 0
>>begin

% Let's read the input string
/s(%stdin)(r)file 999 string readline pop def

% If we want to use the token operator, we have to replace (, [, ), ] and / to get meaningful results
% We use kind of an encoding array (familiar to PostScripters) to map those codes to o, c, and d.
0 1 s length 1 sub{        % index
  s exch                   % string index
  [0 1 255{}for] dup       % string index translationArray translationArray
  [(\(o)  ([o)  (\)c)  (]c)  (/d)] % string index translationArray translationArray reencodeArray
  {                        % string index translationArray translationArray translationString
    {}forall               % string index translationArray translationArray charCode newCharCode
    put dup                % string index translationArray translationArray
  }forall                  % string index translationArray translationArray
  pop                      % string index translationArray
  3 copy pop               % string index translationArray string index
  get                      % string index translationArray charCode
  get                      % string index translatedCharCode
  put                      % -/-
}for

% Now we can actually start interpreting the string
% We use the stack for storing numbers we read and the dictionary stack for operators that are "waiting"
{                          % number*
  s token not{exit}if      % number* string token
  exch /s exch store       % number* token
  % We try to interpret the token as a number
  {cvr}stopped{            % number* token
    % If interpretation as number fails, we have an operator
    load                   % number* opDict
    % Compare operator precedence with last operator on dictstack
    dup /p get             % number* opDict opPrec
    p                      % number* opDict opPrec prevOpPrec
    le {                   % number* opDict
      % If the last operator on the stack has at least the same precedence, execute it
      currentdict end      % number* opDict prevOpDict
      exch begin           % number* prevOpDict
      /e get exec          % number*
    }{                     % number* opDict
      % If last operator doesn't have higher precedence, put the new operator on the dictstack as well
      begin
    }ifelse
  }if
}loop
% If we're finished with interpreting the string, execute all operators that are left on the dictstack
{{e end}stopped{exit}if}loop
=

টোডো : ক্ষয়ক্ষতির ডান-সহযোগীতা


আহ ... ডিক্সট্যাক: উজ্জ্বল!
luser droog

আমাকে স্ট্যাকওভারফ্লোতে মন্তব্য করার অনুমতি দেওয়া হয়েছে, তাই আমি কিছুটা বিভ্রান্ত হয়ে পড়েছিলাম। এটাই কি স্বাভাবিক যে খ্যাতিটি আলাদাভাবে পরিচালিত হয়, বা আমি আমার লগইনগুলি আঁকিয়েছি?
থমাস ডব্লিউ।

আমি আপনাকে বলতে চেয়েছিলাম যে আপনার সমাধানের সাথে অবশ্যই কিছু ভুল হতে হবে কারণ উপরে দেওয়া তিনটি পরীক্ষার কেসই ব্যর্থ। তবে, আপনি এখনও কী করছেন তা বোঝার চেষ্টা করি নি (কিছু মন্তব্য দুর্দান্ত হবে ;-))।
থমাস ডাব্লু।

1) একবার আপনি যে কোনও সাইটে 200 টি আঘাত করলে আপনি প্রতিটি সাইটে 101 এ শুরু করবেন। অথবা এখানে 50 টি আঘাত করুন। 2) আউহ! আমি ভেবেছিলাম এটি বেসিক ক্যালকুলেটরটির দ্রুত বর্ধন was এমনকী আমি দেখিনি যে বন্ধনী আবশ্যক! এবং আমি এটি খুব ভাল পরীক্ষা করিনি। আচ্ছা ভালো; প্যান্ট ডাউন, কমপক্ষে আমার undies পরিষ্কার!
luser droog

@ লেজারড্রোগ: "@ থমাসডাব্লু" আমাকে মন্তব্য করার জন্য আমন্ত্রণ জানায় না।
থমাস ডব্লিউ।

1

পাইথন 2 , 339 335 বাইট

import re
x,s=input(),re.sub
def f(y):
 y,r=s('- ','+ -',y).split(),['^','*','/','+','-']
 for c in r:
  while c in y:d=y.index(c)-1;a,b=map(float,[y[d],y[d+2]]);y=y[:d]+[((a,-a)[a<0]**b,a*b,a/b,a+b,a-b)[r.index(c)]]+y[d+3:]
 return`y[0]`
w=lambda b:s("[([]+[\d+\-*/^ .]*[)\]]",lambda m:f(m.group()[1:]),s(' +',' ',b))
print f(w(w(x)))

এটি অনলাইন চেষ্টা করুন!

  • 4 `ব্যাকটিক্স সহ স্ট্র (এক্স) পরিবর্তন করে -4 বাইট!

0

পোস্টস্ক্রিপ্ট, 1000 695 665 494

থমাস ডাব্লু থেকে ধারণা চুরি করেছে। যুক্ত বৈশিষ্ট্য: অপারেটরগুলির আশেপাশে ফাঁকা জায়গা ছাড়া বা তার ছাড়া স্ট্রিং গ্রহণ করে।[বৈশিষ্ট্য সরানো]


ব্যবহার করা বুট করার ARGUMENTSচেয়ে কম %stdin, এবং টেস্ট করা সহজ!


প্যারেন্স সহ কেবল বন্ধনী প্রতিস্থাপনের জন্য বিকল্পটিকে সরলীকৃত করা হয়েছে।

575(1)10:36 PM:ps 0> gsnd -q -- calc2bg.ps '10 - 3 + 2'
9
576(1)10:37 PM:ps 0> gsnd -q -- calc2bg.ps '8 + 6 / 3 - 7 + -5 / 2.5'
1.0
577(1)10:37 PM:ps 0> gsnd -q -- calc2bg.ps '4 + [ ( -3 + 5 ) * 3.5 ] ^ 2 - 12'
41.0

কোড:

/T[/^[/C{exp}/P 4/X{le}>>/*[/C{mul}/P 3/X{lt}>>/[/C{div}/P
3/X{lt}>>/+[/C{add}/P 2/X{lt}>>/-[/C{sub}/P
2/X{lt}>>>>def[/integertype{}/realtype{}/stringtype{V}/nametype{cvlit/N
exch store{P T N get dup/P get exch/X get exec{exit}if C end}loop T N get
begin}91 40 93 41>>begin/V{0 1 2 index length 1 sub{2 copy get
dup where{exch get}if 3 copy put pop pop}for[/N 0/R 0/P 0/C{}>>begin{token
not{exit}if exch/R exch store dup type exec R}loop{P 0 eq{end exit}if C
end}loop}def ARGUMENTS{V ==}forall

অবহেলিত এবং মন্তব্য করেছেন:

%!
%Shunting-Yard Algorithm using dictstack for operators
%invoke with %gsnd -q -- calc2bg.ps [ 'expr1' ]*

%The operator table. C:code P:precedence X:test(implements associativity)
/T[
    /^[/C{exp}/P 4/X{le}>>
    /*[/C{mul}/P 3/X{lt}>>
    /[/C{div}/P 3/X{lt}>>
    /+[/C{add}/P 2/X{lt}>>
    /-[/C{sub}/P 2/X{lt}>>
>>def

%The type-dispatch dictionary
%numbers: do nothing
%string: recurse
%name: process op
[%/integertype{}/realtype{} %now uses `where` below
/stringtype{V}/nametype{
pstack()=
    cvlit/N exch store %stash cur-op
    {
        P %prec(tos)
        T N get %prec(tos) cur-op-dict
        dup/P get %prec(tos) cur-op-dict prec(cur-op)
        exch/X get %prec(tos) prec(cur-op) test(cur-op)
        exec{exit}if %exit if prec(tos) < || <= prec(cur-op)
/C load ==
        C %pop-and-apply
        end
pstack()=
    } loop
    T N get begin %push cur-op
}>>begin

%substitutions
[91 40 93 41>>begin %replace brackets with parens
/V {
    %pre-process
    0 1 2 index length 1 sub {
        2 copy get
        dup where { exch get } if
        3 copy put pop pop
    } for
dup ==

    [/N 0/R 0/P 0/C{}>>begin %dummy base operator and storage
    { token not{exit}if exch /R exch store %extract token, stash Remainder
pstack(>)=
        %dispatch type procedure
        dup type dup where { pop exec }{ pop } ifelse
    R }loop
pstack()=
    {
        P 0 eq{end exit}if %hit dummy op: exit
/C load ==
        C end %pop and apply
    } loop
} def

ARGUMENTS{V ==}forall %iterate through the command-line arguments

@ থমাসডাব্লু আমি ভাবছি যদি এটি আপনাকে মন্তব্য করার জন্য আমন্ত্রণ জানায় works (?)
লুসার droog

আমি comp.lang.posts লিপিতে একই ধারণাটির সম্পূর্ণ বাস্তবায়ন পোস্ট করেছি ।
লুসার droog
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.