सटीक दशमलव के लिए अंश


23

एक प्रोग्राम या फ़ंक्शन लिखें जिसमें दो पूर्णांक दिए गए हैं , b एक स्ट्रिंग को दशमलव संख्या से युक्त एक स्ट्रिंग को आउटपुट करता है जो बिल्कुल a / b का प्रतिनिधित्व करता है

यदि a / b पूर्णांक है, तो बस दशमलव डॉट या अग्रणी शून्य के बिना, आउटपुट का मान रखें:

123562375921304812375087183597 / 2777 -> 44494913907563850333124661
81 / 3 -> 27
-6 / 2 -> -3

यदि a / b पूर्णांक नहीं है, लेकिन आधार 10 में एक परिमित प्रतिनिधित्व है, तो प्रमुख या अनुगामी शून्य (डॉट से पहले एक शून्य को छोड़कर) के बिना मान का उत्पादन करें:

1 / 2 -> 0.5
3289323463 / -250000000 -> -13.157293852

अंत में, यदि और केवल अगर (तो नहीं 0.999...) ए / बी पूर्णांक नहीं है और एक परिमित प्रतिनिधित्व नहीं है, तो परिमित भाग के बाद परिमित भाग का उत्पादन होता है। दोहराव वाला हिस्सा जितना संभव हो उतना छोटा होना चाहिए, और जितनी जल्दी हो सके शुरू करें।

-1 / 3 -> -0.(3)
235 / 14 -> 16.7(857142)
123 / 321 -> 0.(38317757009345794392523364485981308411214953271028037)
355 / 113 -> 3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)

आपका प्रोग्राम आधुनिक डेस्कटॉप पीसी पर 10 सेकंड से कम समय में सभी उपरोक्त उदाहरणों के लिए काम करना चाहिए। बाइट्स में सबसे छोटा कार्यक्रम जीतता है।


@DestructibleWatermelon यह ट्यूरिंग टारपीट्स सहित सभी भाषाओं में बहुत संभव है । (हालांकि वे समय सीमा के साथ संघर्ष कर सकते हैं।)
डेनिस

@DestructibleWatermelon मैं इस धारणा के तहत था कि अधिकांश भाषाएं पूरी तरह से ट्यूरिंग कर रही हैं।
orlp

क्या हम सुरक्षित रूप से मान सकते हैं कि अंश कुछ ऐसा नहीं होगा: 0.3333333333333636333 ...?
brianush1

2
ऐसा लगता है कि PE26 के समाधान की माँग करने का एक लंबा- चौड़ा तरीका है ;)
Conor O'Brien

1
इस प्रश्न का सामान्यीकरण ; संबंधित भी
पीटर टेलर

जवाबों:


3

पर्ल 6 ,  63 58  50 बाइट्स

{->$a,$b {$a~"($b)"x?$b}(|($^a.FatRat/$^b).base-repeating(10))}
{->\a,$b {a~"($b)"x?$b}(|($^a.FatRat/$^b).base-repeating)}
{$/=($^a.FatRat/$^b).base-repeating;$0~"($1)"x?$1}

झसे आज़माओ

अगर आपको परवाह नहीं है कि यह केवल भाजक के साथ काम करेगा जो 64 बिट पूर्णांक में फिट होता है तो इसे केवल 43 बाइट्स तक छोटा किया जा सकता है:

{$/=($^a/$^b).base-repeating;$0~"($1)"x?$1}

विस्तारित:

{
  # store in match variable so that we can
  # use 「$0」 and 「$1」
  $/ = (

    # turn the first value into a FatRat so that
    # it will continue to work for all Int inputs
    $^a.FatRat / $^b

  ).base-repeating;

  # 「$0」 is short for 「$/[0]」 which is the non-repeating part
  $0

  # string concatenated with
  ~

  # string repeat once if $1 is truthy (the repeating part)
  # otherwise it will be an empty Str
  "($1)" x ?$1
}

जिस तरह से आपने अपना उत्तर दिया है वह भ्रमित करने वाला है। आपको अपने पुराने कार्यक्रमों को हटा देना चाहिए, क्योंकि अभी यह एक बहु-पंक्ति कार्यक्रम की तरह दिखता है।
mbomb007

@ mbomb007 मेरे पास गोल्फ पोस्ट करने का मुख्य कारण मार्केटिंग के लिए है, और पर्ल 6. की शिक्षा है। इसलिए मैं भाषा के अधिक दिखाने के लिए पुराने संस्करणों को छोड़ देता हूं। यही कारण है कि मैं शायद ही कभी एक पोस्ट करता हूं जब तक कि मैं वहां किसी प्रकार का स्पष्टीकरण नहीं करता। मैंने इसे बदल दिया है ताकि विभिन्न उदाहरण अलग-अलग कोड ब्लॉक में हों।
ब्रैड गिल्बर्ट

पुराने संस्करण हमेशा पोस्ट के संपादित इतिहास में दिखाई देते हैं।
mbomb007

@ mbomb007 अगर मैं इसे लिखने के कई अलग-अलग तरीकों की कोशिश करने के बाद तक पोस्ट करने की प्रतीक्षा नहीं करता हूं।
ब्रैड गिल्बर्ट 2

फिर हर 5 मिनट में एक को संपादित करें।
mbomb007

8

पायथन 2, 174 बाइट्स

x,y=input()
a=abs(x)
b=abs(y)
r=a%b*10
L=[]
M=''
while~-(r in L):L+=r,;M+=str(r/b);r=r%b*10
i=L.index(r)
t=M[:i]+"(%s)"%M[i:]*(M[i:]>'0')
print"-%d."[x*y>=0:(t>'')+3]%(a/b)+t

मैं इस उत्तर की वैधता के बारे में बिल्कुल आश्वस्त नहीं हूं, लेकिन यह ऊपर दिए गए परीक्षण मामलों और मेरे द्वारा फेंके गए अन्य परीक्षण मामलों के लिए काम किया है। यह एक सही गड़बड़ की तरह दिखता है, इसलिए मुझे यकीन है कि गोल्फ के लिए बहुत जगह है।

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

ध्यान दें कि एल्गोरिथ्म वास्तव में O (n) inऑपरेशन के कारण काफी धीमा है , लेकिन यह उदाहरणों के लिए काफी तेज है।


5

बैच, 349 344 बाइट्स

@echo off
set/ad=%2,i=%1/d,r=%1%%d
if not %r%==0 set i=%i%.&if %r% leq 0 set/ar=-r&if %i%==0 set i=-0.
set d=%d:-=%
set/ae=d
:g
if %r%==0 echo %i%&exit/b
set/ag=-~!(e%%2)*(!(e%%5)*4+1)
if not %g%==1 set/ae/=g&call:d&goto g
set/as=r
set i=%i%(
:r
call:d
if %r%==%s% echo %i%)&exit/b
goto r
:d
set/ar*=10,n=r/d,r%%=d
set i=%i%%n%

संपादित करें: अनावश्यक वर्णों को हटाकर 5 बाइट्स सहेजे गए। "Ungolfed":

@echo off
set /a d = %2
set /a i = %1 / d
set /a r = %1 % d
if not %r%==0 (
    set i=%i%.                  Decimal point is required
    if %r% leq 0 (
        set /a r = -r           Get absolute value of remainder
        if %i%==0 set i=-0.     Fix edge case (-1/3 = 0 remainder -1)
    )
)
set d = %d:-=%                  Get absolute value of divisor
set /a e = d
:g
if %r%==0 echo %i% & exit /b    Finished if there's no remainder
set /a g = gcd(e, 10)           Loop through nonrecurring decimals
if not %g%==1 (
    set /a e /= g
    call :d
    goto g
)
set /a s = r                    Save remainder to know when loop ends
set i=%i%(
:r
call :d
if %r%==%s% echo %i%)&exit/b
goto r
:d                              Add the next decimal place
set /a r *= 10
set /a n = r / d
set /a r %= d
set i=%i%%n%

2
मुझे नहीं पता कि यह कैसे काम करता है, लेकिन मैं आपको इसे बैचो में करने के लिए सराहना करता हूं
अलेक्जेंडर - मोनिका

की क्षमताओं से प्रभावित हूं set /a
जो

2

जावा, ६२० ६०५

गोल्फ कोड:

import static java.math.BigInteger.*;
String f(BigInteger a, BigInteger b){BigInteger[]r=a.divideAndRemainder(b);String s=r[0].toString();if(r[1].signum()<0)s="-"+s;if(!ZERO.equals(r[1])){s+='.';List<BigInteger>x=new ArrayList();List<BigInteger>y=new ArrayList();for(BigInteger d=TEN.multiply(r[1].abs());;){BigInteger[]z=d.divideAndRemainder(b.abs());int i=y.indexOf(z[1]);if(i>-1&&i==x.indexOf(z[0])){for(int j=0;j<i;++j)s+=x.get(j);s+='(';for(int j=i;j<x.size();++j)s+=x.get(j);s+=')';break;}x.add(z[0]);y.add(z[1]);if(ZERO.equals(z[1])){for(BigInteger j:x)s+=j;break;}d=TEN.multiply(z[1]);}}return s;}

नोट: मैं गोल्फ आयात के लिए फ़ंक्शन के हिस्से के रूप में स्थैतिक आयात की गणना करता हूं।

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

यह एक बड़ा कारण है BigInteger। अगर इनपुट्स ओवरफ्लो नहीं हुए longतो यह थोड़ा कम हो सकता है। फिर भी, मुझे उम्मीद है कि इस प्रविष्टि में सुधार के तरीके हैं।

परीक्षण के लिए मुख्य विधि के साथ असम्बद्ध कोड:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import static java.math.BigInteger.*;

public class FractionToExactDecimal {

  public static void main(String[] args) {
    // @formatter:off
    String[][] testData = new String[][] {
      { "123562375921304812375087183597", "2777", "44494913907563850333124661" },
      { "81", "3", "27" },
      { "-6", "2", "-3" },
      { "1", "2", "0.5" },
      { "3289323463", "-250000000", "-13.157293852" },
      { "-1", "3", "-0.(3)" },
      { "235", "14", "16.7(857142)" },
      { "123", "321", "0.(38317757009345794392523364485981308411214953271028037)" },
      { "355", "113", "3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)" }
    };
    // @formatter:on

    for (String[] data : testData) {
      System.out.println(data[0] + " / " + data[1]);
      System.out.println("  Expected -> " + data[2]);
      System.out.print("    Actual -> ");
      System.out.println(new FractionToExactDecimal().f(new BigInteger(data[0]), new BigInteger(data[1])));
      System.out.println();
    }
  }

  // Begin golf
  String f(BigInteger a, BigInteger b) {
    BigInteger[] r = a.divideAndRemainder(b);
    String s = r[0].toString();
    if (r[1].signum() < 0) s = "-" + s;
    if (!ZERO.equals(r[1])) {
      s += '.';
      List<BigInteger> x = new ArrayList();
      List<BigInteger> y = new ArrayList();
      for (BigInteger d = TEN.multiply(r[1].abs());;) {
        BigInteger[] z = d.divideAndRemainder(b.abs());
        int i = y.indexOf(z[1]);
        if (i > -1 && i == x.indexOf(z[0])) {
          for (int j = 0; j < i; ++j)
            s += x.get(j);
          s += '(';
          for (int j = i; j < x.size(); ++j)
            s += x.get(j);
          s += ')';
          break;
        }
        x.add(z[0]);
        y.add(z[1]);
        if (ZERO.equals(z[1])) {
          for (BigInteger j : x)
            s += j;
          break;
        }
        d = TEN.multiply(z[1]);
      }
    }
    return s;
  }
  // End golf
}

कार्यक्रम का उत्पादन:

123562375921304812375087183597 / 2777
  Expected -> 44494913907563850333124661
    Actual -> 44494913907563850333124661

81 / 3
  Expected -> 27
    Actual -> 27

-6 / 2
  Expected -> -3
    Actual -> -3

1 / 2
  Expected -> 0.5
    Actual -> 0.5

3289323463 / -250000000
  Expected -> -13.157293852
    Actual -> -13.157293852

-1 / 3
  Expected -> -0.(3)
    Actual -> -0.(3)

235 / 14
  Expected -> 16.7(857142)
    Actual -> 16.7(857142)

123 / 321
  Expected -> 0.(38317757009345794392523364485981308411214953271028037)
    Actual -> 0.(38317757009345794392523364485981308411214953271028037)

355 / 113
  Expected -> 3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)
    Actual -> 3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)

अच्छा! मुझे लगता है कि आप इसे एक फ़ंक्शन जो स्ट्रिंग लौटाता है, और उस एक स्थान को हटाकर कुछ बाइट्स बचा सकते हैं a, BigInteger। मुझे भी लगता है कि आप उर्फ BigInteger.TENऔर BigInteger.ZERO
फ्राईमईएग्गमैन

@FryAmTheEggman धन्यवाद, मुझे एहसास नहीं था कि स्थैतिक आयात ने अधिक क्रिया संदर्भों पर अंतरिक्ष को बचाया। ऐसा होता है। मुझे कुछ और चीजें भी मिलीं जो मुझे याद थीं, जैसे while (true)-> for (;;)जिसने मुझे forइनिशियलाइज़र में सामान रखने की अनुमति दी , जिससे एक और बाइट बच गई।

सबसे पहले, BigInteger को कैसे बढ़ाया जाए? दूसरा, एक दोहराया शेष यह दोहराने के लिए पर्याप्त है; यदि आप इनपुट को int में सीमित करते हैं तो आप एक int [] को इंडेक्स के रूप में और इंडेक्स को वैल्यू के रूप में उपयोग कर सकते हैं, अगर यह समझ में आता है।
जॉली जोकर

@JollyJoker BigInteger का विस्तार करने के लिए जगह बचाने की कोशिश करने के लिए एक पूरी कक्षा लिखने की आवश्यकता होगी, और मुझे गंभीरता से संदेह है कि ट्रेडऑफ़ काम करेगा। साथ ही, मैं इनपुट को प्रतिबंधित नहीं कर सकता । वैसे भी, BigIntegerमेरे कोड में पाठ के आठ उदाहरण हैं , और मैं नहीं देखता कि उन्हें एक एकल वर्ण वर्ग के नाम पर सिकोड़ने के लिए अधिक कोड को कैसे जोड़ा जाएगा। और निश्चित रूप से निपटने के लिए कोड जोड़ना int[](जो कि BigInteger पहले से ही आंतरिक रूप से करता है) केवल मेरे उत्तर को फूला देगा।

@ जॉलीजॉकर यह भी ध्यान देने योग्य है कि जब तक मैं हर BigInteger विधि को ओवरक्लास की एक आवृत्ति को वापस करने के लिए कॉल नहीं करता, मुझे कई जातियों को जोड़ने की आवश्यकता होगी जो आगे कोड को ब्लोट करते हैं। उपवर्ग के ओवरहेड के लिए व्यर्थ बाइट्स के ऊपर, यह निश्चित रूप से कोड आकार में वृद्धि करेगा।

1

PHP, 277 बाइट्स

list(,$n,$d)=$argv;$a[]=$n;$n-=$d*$r[]=$n/$d^0;!$n?:$r[]=".";while($n&&!$t){$n*=10;$n-=$d*$r[]=$n/$d^0;$t=in_array($n%=$d,$a);$a[]=$n;}if($t){$l=count($a)-($p=array_search(end($a),$a));echo join(array_slice($r,0,2+$p))."(".join(array_slice($r,2+$p,$l)).")";}else echo join($r);

0

गणितज्ञ 198 बाइट्स

i=Integer;t=ToString;a_~h~b_:=f[a/b];f@q_i:= t@q;
f@q_:=""<>{t@IntegerPart[q],".",RealDigits[FractionalPart[q]][[1]]//.{{x___,{k__i}}:> {x,"("<>(t/@{k})<>")"},{x__i,j___String}:>""<> {""<>t/@{x},j}}}

UnGolfed

(* hand over quotient of a, b to function f *)
h[a_, b_] := f[a/b];

(* if the quotient is an integer, return it as a string *)
f[q_Integer] := ToString@q;

(* otherwise, return the integer part, followed by a decimal point ...*)
f[q_] := "" <> {ToString@IntegerPart[q], ".", 

   (* replacing the repeating part (if it exists) between parentheses *)
   RealDigits[FractionalPart[q]][[1]] //. {{x___, {i__Integer}} :> {x, "(" <>(ToString /@ {i}) <> ")"},

   (* and the non-repeating part (if it exists) without parentheses *)
   {x__Integer, i___String} :> "" <> {"" <> ToString /@ {x}, i}}}

टेस्ट

h @@@ {{81, 3}, {-81, 3}, {1, 4}, {-13, 3}, {19, 7}, {3289323463, 25000}, {235, 14}, {1325, 14}}

{"27", "-27", "0.25", "-4। (3)", "2. (714285)", "131572.93852", "16.7 (857142)", "94.6 (428571)"}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.