कुछ आवधिक और गैर-आवधिक भागों को स्वैप करें


21

प्रत्येक परिमेय संख्या के दशमलव प्रतिनिधित्व में p/q, आपके पास एक आवधिक पूंछ, एक गैर-आवधिक सिर और निम्नलिखित प्रारूप में दशमलव बिंदु से पहले एक अनुभाग है:

(before decimal point).(non-periodic)(periodic)

कुछ उदाहरणों में शामिल हैं:

1/70 = 0.0142857... = (0).(0)(142857)
10/7 = 1.428571... = (1).()(428571)            ## no non-periodic part
1/13 = 0.076923... = (0).()(076923)
3/40 = 0.075 = (0).(075)()                    ## no periodic part
-2/15 = -0.13... = -(0).(1)(3)                ## negative
75/38 = 1.9736842105263157894... = (1).(9)(736842105263157894)
                                              ## periodic part longer than float can handle
25/168 = 0.148809523... = (0).(148)(809523)
120/99 = 40/33 = 1.212121... = (1).()(21)
2/1 = 2 = (2).()()                            ## no periodic, no non-periodic
0/1 = 0 = (0).()()
0/2 = 0 = (0).()()
299/792 = 0.37752... = (0).(377)(52)
95/-14 = -6.7857142... = -(6).(7)(857142)
-95/-14 = 6.7857142... = (6).(7)(857142)

आवधिक और गैर आवधिक भागों की अदला-बदली करने की चुनौती है before decimal point, एक नया नंबर बनाने के लिए अकेले छोड़ देना । उदाहरण के लिए:

25/168 = 0.148809523... = (0).(148)(809523)
       => (0).(809523)(148) = 0.809523148148... = 870397/1080000

यदि किसी संख्या में कोई आवधिक भाग नहीं है, तो 0.25उस संख्या को एक नई आवधिक संख्या में बदल दें, और इसके विपरीत।

1/4 = 0.25 = (0).(25)() => (0).()(25) = 0.252525... = 25/99
4/9 = 0.444444... = (0).()(4) => (0).(4)() = 0.4 = 2/5
5/1 = 5 = (5).()() => (5).()() = 5 = 5/1

चुनौती

  • xइनपुट के रूप में एक अंश लें , एक स्ट्रिंग के रूप में, दो इनपुट, एक परिमेय संख्या, या जो भी विधि आपकी भाषा के अनुरूप है।
  • xएक नई संख्या बनाने के लिए दशमलव के आवधिक और गैर-आवधिक भागों को स्वैप करें , अकेले दशमलव से पहले भाग छोड़ दें। आवधिक भाग हमेशा जल्द से जल्द शुरू होता है ताकि गैर-आवधिक भाग यथासंभव कम हो। उदाहरण नीचे हैं।
  • एक नए अंश के रूप में स्वैप की गई संख्या लौटाएं। इनपुट आवश्यक रूप से कम नहीं है हालांकि आउटपुट होना चाहिए। इनपुट प्रारूप को आउटपुट प्रारूप से भिन्न करने की अनुमति है।
  • अंश pकी xऔर एक लाख या उससे कम का निरपेक्ष मान विभाजक के साथ एक पूर्णांक हो जाएगा qकी xएक हो जाएगा गैर शून्य दस लाख या उससे कम का निरपेक्ष मान के साथ पूर्णांक।
  • परिणाम का अंश rऔर भाजक sएक मिलियन से कम होने की गारंटी नहीं है। इन नंबरों के आवधिक भागों की लंबाई को देखते हुए, यह अनुशंसा की जाती है कि आप सीधे फ्लोट में परिवर्तित होने से बचें।
  • यह कोड गोल्फ है। बाइट्स जीत में सबसे छोटा जवाब।

उदाहरण

1/70 = (0).(0)(142857)     => (0).(142857)(0) = (0).(142857)() = 0.142857 = 142857/1000000
10/7 = (1).()(428571)      => (1).(428571)() = 1.428571 = 1428571/1000000
1/13 = (0).()(076923)      => (0).(076923)() = 0.076293 = 76923/1000000
3/40 = (0).(075)()         => (0).()(075) = 0.075075... = 75/999 = 25/333
-2/15 = -(0).(1)(3)        => -(0).(3)(1) = -0.311111... = -28/90 = -14/45
75/38 = (1).(9)(736842105263157894)
      => (1).(736842105263157894)(9) = (1).(736842105263157895)()  ## since 0.999... = 1
      = 1.736842105263157895 = 1736842105263157895/1000000000000000000
      = 347368421052631579/200000000000000000
25/168 = (0).(148)(809523) => (0).(809523)(148) = 0.809523148148... = 870397/1080000
120/99 = (1).()(21)        => (1).(21)() = 1.21 = 121/100
2/1 = (2).()()             => (2).()() = 2 = 2/1
0/1 = (0).()()             => (0).()() = 0 = 0/1
0/2 = (0).()()             => (0).()() = 0 = 0/1
299/792 = (0).(377)(52)    => (0).(52)(377) = 0.52377377... = 2093/3996
95/-14 = -(6).(7)(857142)  => -(6).(857142)(7) = -6.857142777... = -12342857/1800000
-95/-14 = (6).(7)(857142)  => (6).(857142)(7) = 6.857142777... = 12342857/1800000

0परीक्षण के मामले के अंत में एक लापता है 2 ( 10/7): 1428571/100000होना चाहिए 1428571/1000000
जंगवान मिन

1
जैसा कि कहा गया है कि किसी दिए गए इनपुट के लिए एक अद्वितीय उत्तर नहीं होगा। 1/7के रूप में प्रतिनिधित्व किया जा सकता है (0).()(142857) या (0).(1)(428571), 1निरूपित किया जा सकता के रूप में (1).()(), (0).()(9), (0).()(99), (0).(9)(9), आदि
ngenisis

@ngenisis उदाहरणों में निहित था, लेकिन मैंने इसे स्पष्ट कर दिया है। प्रतिक्रिया के लिए धन्यवाद :)
शर्लक

@ R.Kap मैंने पहले ही चुनौती में कहा है कि यहां तैरने से बचने के लिए सबसे अच्छा है। फ्लोट में कनवर्ट किए बिना किसी संख्या के दशमलव अंकों को खोजने के तरीके हैं। मुझे उम्मीद है कि यह आपके सवाल का जवाब देगा :)
शेरलाक

क्या p और q दोनों ऋणात्मक हो सकते हैं?
edc65 13

जवाबों:


5

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

def x(n,d):
 L=len;s=cmp(n*d,0);n*=s;b=p=`n/d`;a={};n%=d
 while not n in a:
  a[n]=p;q=n/d;n=n%d
  if q==0:n*=10;p+=' '
  p=p[:-1]+`q`
 p=p[L(a[n]):];a=a[n][L(b):]
 if n==0:p=''
 n=int(b+p+a);d=10**L(p+a)
 if a!='':n-=int(b+p);d-=10**L(p)
 import fractions as f;g=f.gcd(n,d);return(n/g*s,d/g)

Ungolfed संस्करण, दोनों अजगर 2 और 3 में काम करता है। दशमलव प्रतिनिधित्व को भी प्रिंट करता है।

def x(n,d):
# sign handling
 s=n*d>0-n*d<0
 n*=s
# b, a, p: BEFORE decimal, AFTER decimal, PERIODIC part
 b=p=str(n//d)
 a={}
 n%=d
# long division
 while not n in a:
  a[n]=p
  q=n//d
  n=n%d
  if q==0:
   n*=10
   p+=' '
  p=p[:-1]+str(q)
# a/p still contain b/ba as prefixes, remove them
 p=p[len(a[n]):]
 a=a[n][len(b):]
 if n==0: p=''
# print decimal representation
 print("(" + b + ").(" + a + ")(" + p + ")")
# reassemble fraction (with a and p exchanged)
 n=int(b+p+a)
 d=10**len(p+a)
 if a!='':
  n-=int(b+p)
  d-=10**len(p)
# reduce output
 from fractions import gcd
 g=gcd(n,d)
 return(n//g*s,d//g)

कोशिश करेंd=10**len(p+a)
शर्लक

1
यहाँ आसान परीक्षण के लिए एक TIO लिंक है: इसे ऑनलाइन आज़माएं!
क्रिक्सी लिथोस

आपके उत्तर पर शाबाश: डी। कुछ आगे गोल्फ युक्तियाँ: उपयोग अधिक अर्धविराम जहां संभव हो, लाइन में अंतरिक्ष से छुटकारा पाने के if n==0: p=''लिए, उपयोग ``आप का उपयोग हर जगह में str, इस तरह के रूप `n/d`के बजाय str(n/d), और नाम बदलने lenके लिए Lके साथ L=len;समारोह की शुरुआत में।
शर्लक

@ शर्लक 9 मुझे बैकटिक्स के बारे में भी नहीं पता था। सारी सलाह के लिए धन्यवाद।
रेनर पी।

एक समस्या नहीं है। यहाँ कुछ और हैं: डी दो स्थानों के लिए अर्धविराम: n=int(b+p+a);d=10**L(p+a)और import fractions as f;g=f.gcd(n,d);return(n/g*s,d/g)। इसके अलावा, मुझे आपके वर्तमान संपादन के लिए 295 बाइट्स मिलेंगे। क्या कोई अतिरिक्त न्यूलाइन है जिसे आप छोड़ना भूल रहे हैं?
शर्लक

2

जेली , 102 101 89 87 83 81 79 78 77 74 बाइट्स

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

गोल्फ संपादन: -1 बाइट Xanderhall के लिए धन्यवाद। सही लॉजिकल नहीं बिलिन का उपयोग नहीं करने से बग फिक्स। -13 बाइट्स द न्यूमेरिक लिंक्स को गोल्फ से। dडेनिस के लिए धन्यवाद के साथ नकारात्मक के लिए एक बग फिक्स करने से +1 बाइट । लिंक को पुनर्संरचित किया ताकि अंश उत्पन्न करने वाले सभी एक लिंक में हों। दूसरे और तीसरे लिंक के संयोजन से -2 बाइट्स। -4 बाइट्स तीसरे और चौथे लिंक के कुछ सामान्य तत्वों को दूसरे लिंक और मुख्य लिंक को स्थानांतरित करने से। कुछ सुपरफ्लस चेन ऑपरेटरों को हटाने से -2 बाइट्स। -2 अंश संख्या को फिर से व्यवस्थित करने से। -1 बाइट Ḣ€को दूसरी कड़ी के अंत तक ले जाने से। मुख्य लिंक में एक बग फिक्स्ड। -1 बाइट को बदलने Ṫ ... ,Ḣसे Ḣ ... ṭ। मुख्य लिंक में अंश लिंक ले जाने से -3 बाइट्स।

गोल्फ सुझाव का स्वागत करते हैं! इसे ऑनलाइन आज़माएं!

2ị×⁵d⁴
ÇÐḶ,ÇÐĿḟ@\µḢḅÐfıṭµḢḊṭµḢ€€µF,ḢQ
ÇL€⁵*
×Ṡ©⁸×%µ³,⁴A:/;Ѐ2ĿḌ×®,Ç_/€µ:g/

व्याख्या

सबसे पहले, मैं मुख्य लिंक की व्याख्या करूँगा , जो अन्य लिंक को कॉल करता है।

×Ṡ©⁸×%µ³,⁴A:/;Ѐ2ĿḌ×®,Ç_/€µ:g/  Main link. Left argument: n (int), right argument: d (int)
                                Split into three chains.
×Ṡ©⁸×%  First chain
×       Multiply n by d.
 Ṡ©     Yield sign(n*d) and save it to the register.
   ⁸×   Multiply by n.
     %  Yield n*sgn(n*d) modulo d.

µ³,⁴A:/;Ѐ2ĿḌ×®,Ç_/€  Second chain
                        What follows is the formula for the numerator.
                        (+) means combining the digits of two numbers into one number.
                        ( `integer (+) periodic (+) non-periodic` - `integer (+) periodic` )
µ                     Start a new monadic chain with n*sgn(n*d)%d.
 ³,⁴                  Pair the original two arguments as a nilad.
    A                 Get their absolute values.
     :/               Integer divide to get the integer part of abs(n)/abs(d).
          2Ŀ          Yield the results of the second link.
       ;Ѐ            Append the integer part to each item in the right argument.
                        This appends to both lists from the second link.
            Ḍ         Convert each list from decimal to integer.
             ×®       Multiply by sign(n*d) retrieved from the register.
               ;Ç     Concatenate with the result of the third link (our new denominator).
                 _/€  Reduced subtract over each list.
                        Yields the proper numerator and denominator.

µ:g/  Third chain
µ     Start a new monadic chain with [numerator, denominator].
  g/  Yield gcd(numerator, denominator).
 :    Divide [numerator, denominator] by the gcd.
      Return this as our new fraction.

फिर, पहला लिंक जो अंकों को प्राप्त करता है।

2ị×⁵d⁴  First link: Gets the decimal digits one at a time in the format:
          [digit, remainder to use in the next iteration]
2ị      Gets the second index (the remainder).
  ×⁵    Multiply by 10.
    d⁴  Divmod with d.

अब, दूसरा लिंक जो आवधिक और गैर-आवधिक भागों को प्राप्त करता है n/d, और बहुत से अन्य भारी उठाने का।

ÇÐḶ,ÇÐĿḟ@\µḢḅÐfıṭµḢḊṭµḢ€€µF,ḢQ  Second link: Loops the first link,
                                  separates the periodic digits and non-periodic digits,
                                  removes the extras to get only the decimal digits,
                                  and prepares for the third and fourth links.
                                Split into five chains.
ÇÐḶ,ÇÐĿḟ@\  First chain
ÇÐḶ         Loop and collect the intermediate results **in the loop**.
    ÇÐĿ     Loop and collect **all** of the intermediate results.
   ,        Pair into one list.
       ḟ@\  Filter the loop results out the list of all results,
              leaving only [[periodic part], [non-periodic part]].

µḢḅÐfıṭµḢḊṭ  Second and third chains
µ            Start a new monadic chain.
 Ḣ           Get the head [periodic part].
   Ðf        Filter out any [0, 0] lists from a non-periodic number,
  ḅ  ı        by converting to a complex number before filtering.
               Only removes 0+0j. This removes extra zeroes at the end.
      ṭ      Tack the result onto the left argument again.
       µ     Start a new monadic chain.
        Ḣ    Get the head [non-periodic and extra baggage].
         Ḋ   Dequeue the extra baggage.
          ṭ  Tack the result onto the left argument again.

µḢ€€µF,ḢQ  Fourth and fifth chains
µ          Start a new monadic chain with the processed periodic and non-periodic parts.
 Ḣ€€       Get the head of each list (the digits)
            in both the periodic and non-periodic parts.
    µ      Start a new monadic chain with these lists of digits.
     F     Left argument flattened.
       Ḣ   Head of the left argument.
      ,    Pair the flattened list and the head into one list.
        Q  Uniquify this list. (Only removes if non-periodic part is empty)
             Removes any duplicates resulting from a purely periodic n/d.

तीसरे लिंक है, जो हमारे नए भाजक अर्जित करता है।

ÇL€⁵*  Third link: Generate the denominator.
         What follows is the formula for the denominator.
         ( 10**(num_digits) - ( 10**(num_periodic_digits) if len(non-periodic) else 0 ) )
Ç      Yield the results of the second link.
 L€    Get the length of each item in the list.
         The number of digits in total and the number of digits in the periodic part.
   ⁵*  10 to the power of each number of digits.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.