स्टर्न-ब्रोकोट पेड़ में एक अंश की स्थिति का पता लगाएं


11

स्टर्न-Brocot पेड़ भिन्न की एक द्विआधारी पेड़ जहां प्रत्येक अंश अंश और यह पड़ोसी ऊपर के स्तर में दो भिन्न के हरों जोड़कर हासिल कर ली है।

यह के साथ शुरू से उत्पन्न होता है 0/1और 1/0"के रूप में अंत बिंदु अंशों", और वहाँ से, इसलिए की तरह एक साथ अंशों और उन अंशों का हरों जोड़ने, द्वारा भिन्न के प्रत्येक लगातार जोड़ी के बीच एक अंश रखकर पुनरावृत्ति:

0.  0/1                                                             1/0
1.  0/1                             1/1                             1/0
2.  0/1             1/2             1/1             2/1             1/0
3.  0/1     1/3     1/2     2/3     1/1     3/2     2/1     3/1     1/0
4.  0/1 1/4 1/3 2/5 1/2 3/5 2/3 3/4 1/1 4/3 3/2 5/3 2/1 5/2 3/1 4/1 1/0

स्टर्न-Brocot पेड़ (से प्रत्येक चरण में nवें यात्रा), देखते हैं 2^n + 1अनुक्रम में तत्व है, जो करने के लिए हम से एक अंश कारण बताना कर सकते हैं 0/2^nकरने के लिए 2^n/2^n। प्रत्येक नया पुनरावृत्ति बस लगातार अंशों के प्रत्येक जोड़े के बीच एक अंश "आधा" सम्मिलित करता है।

यह स्टर्न-ब्रोकोट पेड़ को सकारात्मक तर्कसंगत संख्याओं और 0 और 1 के बीच द्विआधारी अंशों के बीच एक-से-एक मानचित्रण बनाता है, जिससे यह भी प्रमाण मिलता है कि दोनों सेटों में समान हृदयता है।

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

इनपुट और आउटपुट के उदाहरण नीचे दिए गए हैं:

2/3 -> 3/8   (4th number in iteration 3)
4/7 -> 9/32  (between 1/2 and 3/5 in the chart above)
1/1 -> 1/2   (middle number in the first iteration)

जिन इनपुटों का आपको समर्थन करने की आवश्यकता नहीं है, वे संदर्भ के लिए शामिल हैं:

0/1 -> 0/1   (0/1 is considered the left number)
1/0 -> 1/1   (1/0 is considered the rightmost number)

इस लक्ष्य को प्राप्त करने के लिए किसी भी भाषा में सबसे छोटा कार्यक्रम जीत जाता है।


क्या कोई इनपुट / आउटपुट आवश्यकताएं हैं? उदाहरण क्या आपके संदर्भ समाधान के अनुसार बस एक कार्य पर्याप्त है, या क्या यह एक स्टैंड-अलोन प्रोग्राम होने की आवश्यकता है? क्या अंश आउटपुट स्वरूप मायने रखता है?
डैरेन स्टोन

एक फ़ंक्शन पर्याप्त है। मैं समस्या के वर्णन में स्पष्ट कर दूंगा।
जो जेड

मुझे इसके बारे में सोचने में थोड़ी देर हो गई है; मैं शायद कल इसे स्पष्ट करने की कोशिश करूंगा।
जो जेड

2
ठीक है, मुझे लगता है कि आपके मन में जो आपत्ति है वह पेड़ में प्रत्येक गहराई को एक स्थिर हर 2 ^ (गहराई + 1) और संख्यात्मक 1, 3, 5, 7, ... बाईं ओर से असाइन करना है।
पीटर टेलर

1
यह निर्माण की एक वैकल्पिक तरीका 1 पर चौड़ाई-पहले के आदेश शुरुआत में पेड़ के नोड्स (यानी पहले नंबर पर है 1/1 => 1, 1/2 => 2, 2/1 => 3, 1/3 => 4, आदि)। यदि नोड के लिए इतनी संख्या उत्पन्न होती है n, तो 2^lg n(बाइनरी लॉग) सबसे अधिक बिट सेट है n, और वांछित बाइनरी अंश है (2*(n - 2^lg n) + 1) / 2^(lg n + 1)। (गेट-उच्चतम-सेट-बिट के साथ एक निर्देश सेट में एक कोडांतरक समाधान का प्रयास करने वाला कोई भी व्यक्ति शायद इस दृष्टिकोण का उपयोग करना चाहेगा)।
पीटर टेलर

जवाबों:


1

GolfScript ( 49 48 46 वर्ण)

{0\@{}{@2*2$2$>!+@@{{\}3$)*}:j~1$-j}/\)\,?}:f;

या

{0:x;\{}{.2$<!2x*+:x){\}*1$-{\}x)*}/x@)@,?}:g;

दोनों ऐसे कार्य हैं जो स्टैक पर अंश और हर को लेते हैं और स्टैक पर अंश और हर को छोड़ते हैं। ऑनलाइन डेमो

कोर विचार ठोस गणित खंड 4.5 में pseudocode (मेरे संस्करण में p122) में व्यक्त किया गया है :

while m != n do
    if m < n then (output(L); n := n - m)
             else (output(R); m := m - n)

यदि Ls और Rs की स्ट्रिंग की व्याख्या L = 0 और R = 1 के साथ द्विआधारी मान के रूप में की जाती है, तो दो बार उस मान के साथ एक अंश होता है, और हर एक लंबा होता है।

Golfscripters के लिए रुचि के एक बिंदु के रूप में, यह उन दुर्लभ अवसरों में से एक है जब मैंने उपयोगी पाया है। (ठीक है, मैं केवल इसे लूप काउंटर के रूप में उपयोग करता हूं, लेकिन यह कुछ भी नहीं से बेहतर है)।


1

गणितज्ञ, १३४ ११४ १११ चर

f=#~g~0&;0~g~q_=q;p_~g~q_:=g[#,(Sign[p-#]+q)/2]&@FromContinuedFraction[ContinuedFraction@p/.{x___,n_}:>{x,n-1}]

उदाहरण:

f[2/3]

3/8

f[4/7]

9/32

f[1]

1/2


1

रूबी, १३२ १२५

@JoeZ से संदर्भ समाधान को रगड़ और गला दिया।

def t(n,d)u=k=0;v,j,f,g,b=[1,]*5;c=2
while(z=(f*d).<=>(g*n))!=0;z>0?(j,k=f,g):(u,v=f,g);b=b*2-z;f,g=u+j,v+k;c*=2;end
[b,c]end

उपयोग के उदाहरण:

>> t(2,3)
=> [3, 8]
>> t(4,7)
=> [9, 32]
>> t(1,1)
=> [1, 2]

1

रूबी (69 वर्ण) कॉफ़ीस्क्रिप्ट (59 वर्ण)

यह एक ऐसा कार्य है जो अंश और भाजक को तर्क के रूप में लेता है और एक सरणी देता है जिसमें अंश और भाजक के बाद अंश होता है।

g=(a,b,x=0,y=1)->c=a>=b;a&&g(a-b*c,b-a*!c,2*x+c,2*y)||[x,y]

ऑनलाइन डेमो

यह ऊपर के रूप में मेरे गोल्फस्क्रिप्ट समाधान के रूप में एक ही दृष्टिकोण का उपयोग करता है, लेकिन बहुत अधिक पठनीय है क्योंकि मैं एक सरणी में बॉक्सिंग और अनबॉक्सिंग के बारे में चिंता किए बिना 4 चर का उपयोग कर सकता हूं। मैंने CoffeeScript चुना क्योंकि यह उपसर्ग चर के साथ नहीं है $(उदाहरण के लिए PHP में सहेजे गए 20 वर्ण), में शॉर्ट फ़ंक्शन डेफिनिशन सिंटैक्स है जो डिफ़ॉल्ट पैरामीटर मानों की अनुमति देता है (इसलिए f(a,b,x,y)फ़ंक्शन में लपेटने की कोई आवश्यकता नहीं है g(a,b) = f(a,b,0,1)), और मुझे बूलियंस को पूर्णांक के रूप में उपयोग करने देता है उपयोगी मूल्यों के साथ अभिव्यक्ति। जो लोग इसे नहीं जानते हैं, उनके लिए CoffeeScript में मानक C- शैली टर्नरी ऑपरेटर ( C?P:Q) नहीं है, लेकिन मैं C&&P||Qयहां विकल्प देने में सक्षम हूं क्योंकि Pयह कभी भी गलत नहीं होगा।

यकीनन अधिक सुरुचिपूर्ण, लेकिन inarguably कम छोटा है, विकल्प को बार-बार घटाव को विभाजन और मोडुलो के साथ बदलना है:

f=(a,b,x=0,y=1,p=0)->a&&f(b%a,a,(x+p<<b/a)-p,y<<b/a,1-p)||[x+p,y]

(65 चार्ट; ऑनलाइन डेमो )। इसे इस तरह से लिखना यूक्लिड के एल्गोरिथ्म के साथ संबंध को उजागर करता है।


आपको उन कोष्ठकों की आवश्यकता नहीं है a<bजिनके चारों ओर आपको एक चार बचाता है। Inlining cएक और दो देता है। तुम f=->a,b,x=0,y=1{...}भी छोटी परिभाषा के लिए वाक्यविन्यास पर विचार कर सकते हैं ।
हावर्ड

@ हावर्ड, मुझे नहीं पता कि रूबी के कौन से संस्करण का आप उपयोग कर रहे हैं, लेकिन अगर मैं उन कोष्ठकों को हटाने या उस फ़ंक्शन सिंटैक्स का उपयोग करने का प्रयास करता हूं तो मुझे एक सिंटैक्स त्रुटि मिलती है।
पीटर टेलर

के c=a<b ?बाद एक अतिरिक्त स्थान के साथ प्रयास करें b। अन्यथा प्रश्न-पत्र का हिस्सा माना जाता है b
हावर्ड

0

अजगर - 531

अंतिम स्थान के संदर्भ समाधान के रूप में सेवा करने के लिए पाइथन में एक अनियंत्रित समाधान:

def sbtree(n, d): 
    ufrac = [0, 1]
    lfrac = [1, 0]
    frac = [1, 1]
    bfrac = [1, 2]
    while(frac[0] * d != frac[1] * n): 
        if(frac[0] * d > frac[1] * n): 
            # push it towards lfrac
            lfrac[0] = frac[0]
            lfrac[1] = frac[1]
            bfrac[0] = bfrac[0] * 2 - 1 
        elif(frac[0] * d < frac[1] * n): 
            # push it towards ufrac
            ufrac[0] = frac[0]
            ufrac[1] = frac[1]
            bfrac[0] = bfrac[0] * 2 + 1 
        frac[0] = ufrac[0] + lfrac[0]
        frac[1] = ufrac[1] + lfrac[1]
        bfrac[1] *= 2
    return bfrac

यह बस तथ्य का लाभ लेने, भिन्न के बीच एक द्विआधारी खोज करता है कि mediant किसी भी दो भिन्न के उन दो भिन्न के मूल्यों के बीच हमेशा होगा।


0

GolfScript, 54 वर्ण

'/'/n*~][2,.-1%]{[{.~3$~@+@@+[\]\}*].2$?0<}do.@?'/'@,(

टास्क में निर्दिष्ट रूप में इनपुट STDIN पर दिया जाना चाहिए। आप कोड को ऑनलाइन आज़मा सकते हैं

> 4/7
9/32

> 9/7
35/64

> 5/1
31/32

0

गणितज्ञ १३hem

एलेफाल्फा की प्रक्रिया के रूप में सुव्यवस्थित नहीं है, लेकिन यह अब तक का सबसे अच्छा उत्पादन करने में सक्षम है।

q_~r~k_:=Nest[#+Sign@k/(2Denominator@# )&,q,Abs@k]  
g@d_:=
Module[{l=ContinuedFraction@d,p=-1},
l[[-1]]-=1;
(p=-p;# p)&/@l]
h[q_]:=Fold[r,1/2,g@q]

परिक्षण

h[2/3]
h[4/7]
h[1]

3/8
9/32
1/2


0

जावास्क्रिप्ट 186

f=(p1,q1,p2,q2)=>{if(p1*q2+1==p2*q1){return{p:p1+p2,q:q1+q2}}let p,q,pl=0,ql=1,ph=1,qh=0;for(;;){p=pl+ph;q=ql+qh;if(p*q1<=q*p1){pl=p;ql=q}else if(p2*q<=q2*p){ph=p;qh=q}else return{p,q}}}

कम हो सकता है, लेकिन मुझे पठनीय गोल्फ पसंद है


0

हास्केल , 125 बाइट्स

n((a,b):(c,d):r)=(a,b):(a+c,b+d):n((c,d):r)
n a=a
z=zip[0..]
t x=[(j,2^i)|(i,r)<-z$iterate n[(0,1),(1,0)],(j,y)<-z r,x==y]!!0

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

एक जोड़ी के रूप में इनपुट और आउटपुट (n,d)

संक्षिप्त विवरण:

nप्रत्येक जोड़ी अंशों को देखकर और पहले और पुनरावृत्ति के बीच नए को सम्मिलित करने से अगली पंक्ति का निर्माण करता है (जो दूसरा अंश वहीं डाल देगा)। आधार मामला बहुत सरल है क्योंकि यह मूल रूप से सिर्फ पहचान समारोह है। tसमारोह है कि समारोह अनिश्चित काल के लिए सिर्फ दो सीमा दशमलव वाले प्रारंभिक अवस्था बंद आधारित iterates। tफिर प्रत्येक पंक्ति ( i) और पंक्ति में प्रत्येक आइटम को अनुक्रमित करता है ( j) और पहले अंश के लिए खोज करता है जो कि हम जो खोज रहे हैं उससे मेल खाता है। जब यह पाता है तो यह jअंश के 2^iरूप में और हर के रूप में पैदावार देता है।

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