महत्वपूर्ण आंकड़ों के साथ अभिव्यक्तियों का मूल्यांकन करें


10

एक अभिव्यक्ति को देखते हुए, आपका कार्य इसका मूल्यांकन करना है। हालाँकि, आपका उत्तर आवश्यकता से अधिक अंक नहीं दिखा सकता है, क्योंकि इससे वास्तविकता की तुलना में अधिक सटीक माप होने का आभास होता है।

किसी संख्या में कितने महत्वपूर्ण आंकड़े हैं, यह वैज्ञानिक अंकन में लिखे जाने पर कितने अंकों का होता है, जिसमें दशमलव बिंदु मौजूद होने पर अंत में शून्य सहित। उदाहरण के लिए, 1200क्योंकि यह है 2 महत्वपूर्ण आंकड़े है 1.2*10^3लेकिन 1200.4 महत्वपूर्ण आंकड़े है और 1200.05 महत्वपूर्ण आंकड़े है।

जब दो संख्याओं को जोड़ते हैं, तो परिणाम को उसी संख्या में स्थानों पर गोल किया जाना चाहिए, जिस संख्या का सबसे कम महत्वपूर्ण अंक बाईं ओर सबसे दूर है। उदाहरण के लिए, 1200 + 3 = 1200(1200 के बाद से सैकड़ों जगह पर सैकड़ों की संख्या में गोल किया जाता है) 1200.01 + 3 = 1203, और 4.59 + 2.3 = 6.9। ध्यान दें कि 5गोल है। यही नियम घटाव पर लागू होता है। 0लोगों के लिए जगह है। ध्यान दें कि जोड़ना और घटाना महत्वपूर्ण अंकों की संख्या पर निर्भर नहीं करता है। उदाहरण के लिए,999 + 2.00 = 1001क्योंकि १ ९९९ को लोगों के स्थान पर रखा गया है और २.०० को सौवें स्थान पर गोल किया गया है; कम स्थानों के लिए एक राउंड 999 है, इसलिए परिणाम, 1001.00, उसी स्थान पर भी गोल होना चाहिए। इसी तरह, 300 + 1 - 300 बिल्कुल 1 के बराबर है, लेकिन 300 को सैकड़ों जगह पर रखा जाता है, इसलिए अंतिम परिणाम को भी सैकड़ों जगह पर गोल किया जाना चाहिए, जिससे 0. 300. + 1 - 300 हो जाएगा। दूसरा हाथ।

दो संख्याओं को गुणा या विभाजित करते समय, संख्या के महत्वपूर्ण अंकों की संख्या को कम से कम महत्वपूर्ण अंकों के साथ गोल करें। उदाहरण के लिए, 3.839*4=20क्योंकि सटीक मान, से 15.356लेकर केवल एक महत्वपूर्ण आंकड़ा है। इसी तरह, चूंकि दोनों संख्याओं में एक महत्वपूर्ण संख्या है, लेकिन चूंकि दोनों संख्याओं में 3 महत्वपूर्ण आंकड़े हैं। 1 महत्वपूर्ण आंकड़ा है परिभाषित किया गया है।204100/4=30100./4.00=25.00

भाव केवल शामिल होंगे *, /, +, और -, (और कोष्ठक)। संचालन के आदेश का पालन किया जाना चाहिए और हर ऑपरेशन के बाद परिणाम गोल किए जाने चाहिए । यदि कोष्ठक जोड़ या घटाव या गुणा और भाग की एक स्ट्रिंग में छोड़ दिए जाते हैं, तो सभी ऑपरेशन पूरा होने के बाद गोल होते हैं। उदाहरण के लिए, 6*0.4*2 = 5(एक महत्वपूर्ण आंकड़ा), जबकि 0.4*(2*6)=0.4*10=4और (6*0.4)*2=2*2=4

इनपुट : एक स्ट्रिंग, जिसमें एक अभिव्यक्ति है ()*/+-और अंक हैं। चीजों को सरल बनाने के लिए, -केवल एक घटाव ऑपरेटर के रूप में उपयोग किया जाएगा, नकारात्मक संख्याओं को सूचित करने के लिए नहीं; हालाँकि, उत्तर अभी भी नकारात्मक हो सकते हैं और उन्हें -उपसर्ग के रूप में आवश्यकता होगी ।

आउटपुट : अभिव्यक्ति का परिणाम, मूल्यांकन किया गया और अंकों की सही संख्या तक पहुंच गया। ध्यान दें कि के 25लिए गलत है 25.0

परीक्षण के मामले :

3 + 0.5 --> 4
25.01 - 0.01 --> 25.00
4*7*3 --> 80
(4*7)*3 --> 90
(8.0 + 0.5)/(2.36 - 0.8 - 0.02) --> 5.7
6.0 + 4.0 --> 10.0
5.0 * 2.0 --> 10.0
1/(2.0 * (3.0 + 5.0)) --> 0.06
0.0020 * 129 --> 0.26
300 + 1 - 300 --> 0
0 - 8.8 --> -9
3*5/2*2 --> 20

एज मामले: की समस्या पर विचार करें 501*2.0। सटीक मूल्य है 1002। मुद्रण 1002बहुत सारे महत्वपूर्ण आंकड़े देता है (4, जब हमें 2 की आवश्यकता होती है) लेकिन 1000बहुत कम देता है (1, जब हमें 2 की आवश्यकता होती है)। इस मामले में, आपके कार्यक्रम को 1000वैसे भी प्रिंट करना चाहिए ।

यह स्रोत महत्वपूर्ण अंकों को भी समझाता है: http://www.purplemath.com/modules/rounding2.htm


" समान स्थानों की संख्या " से आपका क्या अभिप्राय है ? क्या यह " महत्वपूर्ण आंकड़ों की समान संख्या " के समान है ? आप इसके लिए एक बढ़त मामले चाहते हैं, 999 + 2.00
पीटर टेलर

निश्चित रूप 300 + 1 - 300से परिवर्धन और घटाव का एक स्ट्रिंग है, इसलिए अंत तक गोल होने की आवश्यकता नहीं है। (300 + 1) - 300शून्य होगा।
नील

जवाबों:


9

जावा 11, 1325 1379 1356 1336 1290 बाइट्स

import java.math.*;String c(String s)throws Exception{String r="",T=r,a[],b[],z="\\.";int i=0,l,A[],M=0,m=s.length(),j,f=0,q=m;if(s.contains("(")){for(;i<m;){var c=s.charAt(i++);if(f<1){if(c==40){f=1;continue;}r+=c;}else{if(c==41&T.replaceAll("[^(]","").length()==T.replaceAll("[^)]","").length()){r+="x"+s.substring(i);break;}T+=c;}}return c(r.replace("x",c(T)));}else{for(a=s.split("[\\+\\-\\*/]"),A=new int[l=a.length];i<l;f=b.length>1&&(j=b[1].length())>f?j:f)M=(j=(b=a[i++].split(z))[0].length())>M?j:M;for(b=a.clone(),i=0;i<l;A[i]=b[i].contains(".")?j=b[i].length()-1:b[i].replaceAll("0*$","").length(),i++)for(q=(j=b[i].replace(".","").length())<q?j:q,j=a[i].split(z)[0].length();j++<M;)b[i]=0+b[i];double R=new Double(new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s)+""),p;for(int x:A)m=x<m?x:m;m=m==M&R%1==0&(int)R/10%10<1&(j=(r=R+"").split(z)[0].length())>m?j-q>1?q:j:R>99?m:R%10==0?r.length()-1:m<1?1:m;R=new BigDecimal(R).round(new MathContext((R<0?-R:R)<1?m-1:m)).doubleValue();r=(m<M&(p=Math.pow(10,M-m))/10>R?(int)(R/p)*p:R)+"";l=r.length()-2;r=(r=f<1?r.replaceAll(z+"0$",""):r+"0".repeat(f)).substring(0,(j=r.length())<m?j:r.contains(".")?(j=r.replaceAll("^0\\.0+","").length())<m?m-~j:m+1:m);for(i=r.length();i++<l;)r+=0;return r.replaceAll(z+"$","");}}

+54 बाइट्स किनारे के मामले को ठीक करने के लिए 501*2.0( 1002पहले परिणाम दिया था, लेकिन अब सही है 1000)।

मुझे अब समझ में आया कि यह चुनौती लगभग दो वर्षों तक अनुत्तरित क्यों थी ..
>>> इस चुनौती में डच भाषा की तुलना में अधिक विशेष मामले हैं, जो कुछ कह रही है .. जावा निश्चित रूप से इस तरह की चुनौतियों (या किसी भी कोडगुल्फ़) के लिए सही भाषा नहीं है उस मामले के लिए चुनौती ..; पी), लेकिन यह एकमात्र ऐसी भाषा है जिसे मैं अच्छी तरह से जानता हूं कि मैं इस तरह की कठिन चुनौती का भी प्रयास कर सकता हूं।

Stringरिक्त स्थान के बिना इनपुट प्रारूप (यदि वह अनुमति नहीं है, तो आप s=s.replace(" ","")विधि के शीर्ष पर (+19 बाइट्स) जोड़ सकते हैं )।

इसे ऑनलाइन आज़माएं।

स्पष्टीकरण:

लंबी पोस्ट के लिए क्षमा करें।

if(s.contains("(")){
  for(;i<m;){
    var c=s.charAt(i++);
    if(f<1){
      if(c==40){
        f=1;
        continue;}
      r+=c;}
    else{
      if(c==41&T.replaceAll("[^(]","").length()==T.replaceAll("[^)]","").length()){
        r+="x"+s.substring(i);
        break;}
      T+=c;}}
  return c(r.replace("x",c(T)));}

इस भाग का उपयोग कोष्ठक युक्त इनपुट के लिए किया जाता है। यह अलग किए गए भागों को प्राप्त करेगा और पुनरावर्ती-कॉल का उपयोग करेगा।

  • 0.4*(2*6)बन जाता है 0.4*A, जहां Aएक पुनरावर्ती कॉल हैc(2*6)
  • (8.3*0.02)+(1.*(9*4)+2.2)बन जाता है A+B, जहां Aएक पुनरावर्ती कॉल है c(8.3*0.02)और Bएक पुनरावर्ती कॉल करने के लिए c(1.*(9*4)+2.2)→ जो बदले में हो जाता है 1.*C+2.2, जहां Cएक पुनरावर्ती कॉल हैc(9*4)

for(a=s.split("[\\+\\-\\*/]"),A=new int[l=a.length];
    i<l;
    f=b.length>1&&(j=b[1].length())>f?j:f)
  M=(j=(b=a[i++].split(z))[0].length())>M?j:M;

इस पहले लूप का उपयोग मूल्यों को भरने के लिए किया जाता है Mऔर k, जहां Mमहत्वपूर्ण आंकड़ों के संबंध में सबसे बड़ा पूर्णांक-लंबाई और kसबसे बड़ी दशमलव-लंबाई है।

  • 1200+3.0बन जाता है M=2, k=1( 12, .0)
  • 999+2.00बन जाता है M=3, k=2( 999, .00)
  • 300.+1-300.बन जाता है M=3, k=0( 300, .)

for(b=a.clone(),i=0;
    i<l;
    A[i]=b[i].contains(".")?j=b[i].length()-1:b[i].replaceAll("0*$","").length(),i++)
  for(q=(j=b[i].replace(".","").length())<q?j:q,
      j=a[i].split(z)[0].length();
      j++<M;)
    b[i]=0+b[i];

इस दूसरे लूप का उपयोग सरणियों को भरने के लिए Aऔर bसाथ ही मूल्य के लिए किया जाता है q, जहां Aमहत्वपूर्ण आंकड़ों की मात्रा है, bमिलान करने के लिए अग्रणी शून्य के साथ पूर्णांकों को पकड़ो M, और qसबसे कम लंबाई की अवहेलना करने वाले डॉट्स हैं।

  • 1200+3.0बन जाता है A=[2, 5] (12, 00030), b=[1200, 0003.0]और q=2( 30)
  • 999+2.00हो जाता है A=[3, 5] (999, 00200), b=[999, 002.00]और q=3(दोनों 999और 200)
  • 300.+1-300.बन जाता है A=[3, 3, 3] (300, 001, 300), b=[300., 001, 300.]और q=1( 1)
  • 501*2.0बन जाता है A=[3, 4] (501, 0020), b=[501, 002.0]और q=2( 20)

double R=new Double(new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s)+"")

इनपुट को निकालने के लिए एक जावास्क्रिप्ट इंजन का उपयोग करता है, जिसे Rडबल के रूप में सहेजा जाएगा ।

  • 1200+3.0 हो जाता है R=1203.0
  • 999+2.00 हो जाता है R=1001.0
  • 300.+1-300. हो जाता है R=1.0

for(int x:A)
  m=x<m?x:m;

यह mसरणी में सबसे छोटे मान पर सेट होता है A

  • A=[2, 5] हो जाता है m=2
  • A=[3, 5] हो जाता है m=3
  • A=[3, 3, 3] हो जाता है m=3

 m=m==M                // If `m` equals `M`
   &R%1==0             // and `R` has no decimal values (apart from 0)
   &(int)R/10%10<1     // and floor(int(R)/10) modulo-10 is 0
   &(j=(r=R+"").split(z)[0].length())>m?
                       // and the integer-length of R is larger than `m`:
    j-q>1?             //  If this integer-length of `R` minus `q` is 2 or larger:
     q                 //   Set `m` to `q` instead
    :                  //  Else:
     j                 //  Set `m` to this integer-length of `R`
   :R>99?              // Else-if `R` is 100 or larger:
    m                  //  Leave `m` the same
   :R%10==0?           // Else-if `R` modulo-10 is exactly 0:
    r.length()-1       //  Set `m` to the total length of `R` (minus the dot)
   :m<1?               // Else-if `m` is 0:
    1                  //  Set `m` to 1
   :                   // Else:
    m;                 //  Leave `m` the same

यह mकई कारकों पर आधारित है।

  • 999+2.00 = 1001.0& m=3,q=3हो जाता है m=4(क्योंकि m==M(दोनों 3) → R%1==0( 1001.0कोई दशमलव मान नहीं है) → (int)R/10%10<1( (int)1001.0/10बन जाता है 100100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q<=1( 4-3<=1) → ( तो) mपूर्णांक-भाग "1001"( 4) की लंबाई बन जाता है
  • 3.839*4 = 15.356& m=1,q=1रहता है m=1(क्योंकि m==M(दोनों 1) → R%1!=0( 15.356दशमलव मान है) → R<=99R%10!=0( 15.356%10==5.356) → m!=0→ तो यही mरहता है ( 1)
  • 4*7*3 = 84.0और m=1,q=1रहता है m=1(क्योंकि m==M(दोनों 1) → R%1==0( 84.0कोई दशमलव मान होते हैं) → (int)R/10%10>=1( (int)84/10हो जाता है 88%10>=1) → R<=99R%10!=0( 84%10==4) → m!=0→ तो mरहता ही ( 1))
  • 6.0+4.0 = 10.0और m=2,q=2हो जाता है m=3(क्योंकि m!=M( m=2, M=1) → R<=99R%10==0( 10%10==0) → तो mकुल की लंबाई हो जाता है R(ऋण डॉट) "10.0".length()-1( 3))
  • 0-8.8 = -8.8और m=0,q=1बन जाता है m=1(क्योंकि m!=M( m=0, M=1) → R<=99R%10!=0( -8.8%10==-8.8) → m<1→ तो mबन जाता है 1)
  • 501*2.0 = 1001.0& m=3,q=2हो जाता है m=2(क्योंकि m==M(दोनों 3) → R%1==0( 1001.0कोई दशमलव मान नहीं है) → (int)R/10%10<1( (int)1001.0/10बन जाता है 100100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q>1( 4-2>1) → तो mबन जाता है q( 2))

R=new BigDecimal(R).round(new MathContext((R<0?-R:R)<1?m-1:m)).doubleValue();

अब के Rआधार पर गोल किया जाता है m

  • 1001.0और m=4बन जाता है1001.0
  • 0.258और m=3हो जाता है 0.26(क्योंकि abs(R)<1, m-1( 2) के बजाय m=3अंदर प्रयोग किया जाता है MathContext)
  • -8.8और m=1बन जाता है-9.0
  • 1002.0और m=2बन जाता है1000.0

m<M&(p=Math.pow(10,M-m))/10>R?(int)(R/p)*p:R;

Rयदि आवश्यक हो तो पूर्णांक भाग को संशोधित करता है।

  • 300.+1-300. = 1.0& m=3,M=3रहता है 1.0(क्योंकि m>=M→ तो Rवही रहता है 1.0) ( )
  • 0.4*10 = 4.0& m=1,M=2रहता है 4.0(क्योंकि m<M(10^(M-m))/10<=R( (10^1)/10<=4.0→ → 10/10<=4.01<=4.0) → तो यही Rरहता है ( 4.0))
  • 300+1-300 = 1.0& m=1,M=3हो जाता है 0.0(क्योंकि m<M(10^(M-m))/10>R( (10^2)/10>1.0→ → 100/10>1.010>1.0) → इस कारण Rबन जाता 0.0है int(R/(10^(M-m)))*(10^(M-m))( int(1.0/(10^2))*(10^2)int(1.0/100)*1000*1000)

r=(...)+"";                  // Set `R` to `r` as String (... is the part explained above)
l=r.length()-2;              // Set `l` to the length of `R` minus 2
r=(r=k<1?                    // If `k` is 0 (no decimal values in any of the input-numbers)
      r.replaceAll(z+"0$","")
                             //  Remove the `.0` at the end
     :                       // Else:
      r+"0".repeat(f)
                             //  Append `k` zeroes after the current `r`
  ).substring(0,             // Then take the substring from index `0` to:
     (j=r.length())<m?       //  If the total length of `r` is below `m`:
       j                     //   Leave `r` the same
     :r.contains(".")?       //  Else-if `r` contains a dot
       (j=r.replaceAll("^0\\.0+","").length())<m?
                             //   And `R` is a decimal below 1,
                             //   and its rightmost decimal length is smaller than `m`
        m-~j                 //    Take the substring from index 0 to `m+j+1`
                             //    where `j` is this rightmost decimal length
       :                     //   Else:
        m+1                  //    Take the substring from index 0 to `m+1`
     :                       //  Else:
      m);                    //   Take the substring from index 0 to `m`

यह सेट Rकरने के लिए rस्ट्रिंग के रूप में, और संशोधित यह कई कारकों के आधार पर।

  • 1203.0& m=4,k=2हो जाता है 1203.(क्योंकि k>=1→ ऐसा rहो जाता है 1001.000; ) r.length()>=m( 8>=4) → r.contains(".")r.length()>=m( 8>=4) → इंडेक्स 0से m+1( 5) के स्थान पर
  • 6.9& m=2,k=2रहता है 6.9(क्योंकि k>=1→ तो rबन जाता है 6.900; ) r.length()>=m( 5>=2) → r.contains(".")r.length()>=m( 5>=2) → इंडेक्स 0से m+1( 3) के स्थान पर
  • 1.0& m=3,k=0बन जाता है 1(क्योंकि k<1→ ऐसा rबन जाता है 1; ) r.length()<m( 1<3) → सूचकांक 0से r.length()( 1) के स्थान पर
  • 25.0& m=4,k=4हो जाता है 25.00(क्योंकि k>=1→ ऐसा rहो जाता है 25.00000; ) r.length()>=m( 8>=4) → r.contains(".")r.length()>+m( 8>=4) → इंडेक्स 0से m+1( 5) के स्थान पर
  • 0& m=1,k=0रहता है 0(क्योंकि k<1→ तो rरहता है 0; ) r.length()>=m( 1>=1→) !r.contains(".")अनुक्रमणिका 0से m( 1) के स्थान पर)

for(i=r.length();i++<l;)
  r+=0;

यदि आवश्यक हो तो यह पूर्णांक वाले शून्य को फिर से पीछे रखता है।

  • r="12"और R=1200.0बन जाता हैr="1200"
  • r="1"और R=10.0बन जाता हैr="10"
  • r="8"और R=80.0बन जाता हैr="80"

return r.replaceAll(z+"$","");

और अंत में हम परिणाम वापस कर देते हैं, के बाद हमने किसी भी ट्रेलिंग डॉट्स को हटा दिया है।

  • 1203. हो जाता है 1203
  • 5. हो जाता है 5

निश्चित रूप से कुछ सौ बाइट्स से गोल्फ हो सकता है, लेकिन मुझे खुशी है कि अब यह काम कर रहा है। प्रत्येक मामले को समझने में कुछ समय लगा और चुनौती में क्या पूछा जा रहा था। और फिर ऊपर परिणाम प्राप्त करने के लिए बहुत परीक्षण-और-त्रुटि, परीक्षण और पुनर्प्रयास लिया। और ऊपर इस स्पष्टीकरण को लिखते समय मैं अप्रयुक्त कोड के एक और above 50 बाइट्स निकालने में सक्षम था।


1
Upvoted। लेकिन कल्पना की आवश्यकता है कि 501*2.0आउटपुट के लिए 1000(आपको 1000 वैसे भी आउटपुट चाहिए , जिसे मैं "अभी भी" के रूप में व्याख्या करता हूं, या तो नहीं )। शानदार काम वैसे भी।
वीजुन झोउ

1
@ WeijunZhou प्रतिक्रिया के लिए धन्यवाद! मैंने इसे फिर से कुछ सोचा है और किसी भी अन्य मामलों को तोड़ने के बिना किनारे-केस को ठीक करने में सक्षम था। :)
केविन क्रूज़सेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.