सबसे कुशल बाइनरी फ़ंक्शन की गणना करें


13

आज, हम सबसे कुशल बाइनरी फ़ंक्शन की गणना करेंगे। अधिक विशेष रूप से, हम उस फ़ंक्शन की गणना कर रहे हैं, जब फ़ंक्शन को निरंतर इनपुट 0 या अपने स्वयं के आउटपुट पर लागू करने से बनाया जाता है, जो छोटे पूर्णांकों पर उच्च प्राथमिकता रखते हुए, कम से कम संभव अभिव्यक्तियों के साथ सभी सकारात्मक पूर्णांक का प्रतिनिधित्व कर सकता है।

यह फ़ंक्शन निम्नानुसार बनाया गया है:

प्रत्येक पूर्णांक के लिए, 1 से शुरू हो रहा है और ऊपर की ओर जा रहा है, सबसे छोटी अभिव्यक्ति चुनें जिसे हमने अभी तक आउटपुट नहीं दिया है, और उस पूर्णांक को उस अभिव्यक्ति का आउटपुट बनाते हैं। अभिव्यक्ति की लंबाई में संबंध छोटे बाएं तर्क से, और फिर छोटे सही तर्क से टूट जाएगा। यहां देखिए यह कैसे काम करता है:

  • प्रारंभ में, 1 अप्रकाशित है। सबसे छोटा अप्रकाशित अभिव्यक्ति है f(0, 0), इसलिए हम इसे 1 पर सेट करेंगे।

  • अब, 2 अप्रकाशित है। सबसे छोटा असंसाधित भाव f(f(0, 0), 0)= f(1, 0)और f(0, f(0, 0))= है f(0, 1)। छोटे बाएं तर्क की ओर संबंध टूट जाता है, इसलिए f(0, 1) = 2

  • शेष सबसे छोटी असंबद्ध अभिव्यक्ति f(f(0, 0), 0)= है f(1, 0), इसलिए f(1, 0) = 3

  • अब, हम केवल 2 fएस और 3 0एस के साथ अभिव्यक्तियों से बाहर हैं , इसलिए हमें प्रत्येक में से एक को जोड़ना होगा। बाएं तर्क से संबंध तोड़ना, फिर सही तर्क, हम तब f(0, 2) = 4से, प्राप्त करते हैं f(0, f(0, f(0, 0))) = f(0, f(0, 1)) = f(0, 2)

  • जारी रखते हुए, हम हैं f(0, 3) = 5, f(1, 1) = 6, f(2, 0) = 7, f(3, 0) = 8, f(0, 4) = 9, ...

यहाँ एक तालिका है जिसे मैंने पहले कुछ मूल्यों के लिए भरा है:

    0  1  2  3  4  5  6  7  8
 /---------------------------
0|  1  2  4  5  9 10 11 12 13
1|  3  6 14 15 37 38 39 40 41
2|  7 16 42 43
3|  8 17 44 45
4| 18 46
5| 19 47
6| 20 48
7| 21 49
8| 22 50

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

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


A072766 के समान दिखता है , लेकिन f (3, 1) से शुरू होता है।
kennytm

2
यह थोड़ी देर में पहली चुनौती है कि मुझे कुशलता से गणना करने के लिए कुछ पहेलियाँ। मेरा मानना ​​है कि कैटलन संख्या के साथ कुछ संभव है, लेकिन तुरंत एक समाधान के बारे में नहीं सोच सकता। हम्म ...
orlp

2
ठीक है, इसलिए मुझे नहीं लगता कि यह एक अच्छा गोल्फ का जवाब देगा, लेकिन आप इसे उचित रूप से कुशल बनाने के लिए क्या कर सकते हैं, जब तक कि वे अगले कैटलन संख्या से छोटे न हों, तब तक फ़ंक्शन तर्कों से कैटलन संख्याओं को बार-बार घटाएं। तब आप उनके भावों की लंबाई का पता लगा लेते हैं। फिर आप परिणाम की गणना करने के लिए, संशोधन के साथ, इस पेपर से रैंकिंग / अनट्रैकिंग कार्यों का उपयोग कर सकते हैं । शायद यह सब करने के बाद बीच में कोड के बिट्स को 'रद्द करना' संभव हो और एक उचित सुरुचिपूर्ण समाधान मिल जाए।
orlp

दरअसल, मेरी पिछली टिप्पणी से दृष्टिकोण काम नहीं करता है। ((0, (0, (0, 0))), 0)लेक्सिकोग्राफ़िक रूप से छोटा है (((0, 0), 0), (0, 0)), हालाँकि उत्तरार्द्ध में एक छोटा बाएं हाथ है।
orlp

जवाबों:


6

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

f q=head[i|let c=[(-1,0)]:[[(f a,f b)|n<-[0..k],a<-c!!n,b<-c!!(k-n)]|k<-[0..]],(p,i)<-zip(concat c)[0..],p==q]

यहाँ तर्क को तुच्छ माना जाता है (x,y)। ऊपर दिए गए उत्तर के समान है, लेकिन लुकअप सूची में पेड़ों के बजाय बाएं और दाएं सूचकांकों के जोड़े हैं।


1
अच्छा उत्तर! head[...]है [...]!!0और (p,i)<-zip(concat c)[0..]इसे छोटा किया जा सकता है (i,p)<-zip[0..]$id=<<c
लकोनी

सुधार के लिए धन्यवाद! निश्चित रूप id=<<से प्रदर्शनों की सूची में शामिल होने :)
halfflat

5

पायथन 3, 154 बाइट्स

b=lambda n:[(l,r)for k in range(1,n)for l in b(k)for r in b(n-k)]+[0]*(n<2)
def f(x,y):r=sum((b(n)for n in range(1,x+y+3)),[]);return r.index((r[x],r[y]))

यह न तो बहुत तेज़ है और न ही बहुत गोल्फ, लेकिन यह एक शुरुआत है।


5

वाह! मैं वास्तव में एक कुशल संगणना एल्गोरिथ्म बनाने में कामयाब रहा। मुझे पहले इसकी उम्मीद नहीं थी। समाधान काफी सुरुचिपूर्ण है। यह बार-बार अधिक से अधिक घटाता है, फिर 0. के आधार मामले के लिए नीचे सभी तरह से पुनरावृत्ति करता है। इस उत्तर में C (n) फ़ंक्शन कैटलन संख्याओं को दर्शाता है ।

महत्वपूर्ण पहला कदम यह स्वीकार कर रहा है कि लंबाई के शून्य (अर्थात् 0 ही) के सी (0) = 1 मान हैं, सी (1) = 1 लंबाई के मान (अर्थात् एफ (0, 0)), सी (2) = लंबाई दो के दो मान (f (0, f (0, 0)) और f (f (0, 0), 0))।

इसका मतलब है कि यदि हम nth अभिव्यक्ति की तलाश में हैं, और हम सबसे बड़ी k को ऐसे पाते हैं जैसे C (0) + C (1) + ... + C (k) <= n तो हम जानते हैं कि n की लंबाई k है ।

लेकिन अब हम जारी रख सकते हैं! क्योंकि हम जिस अभिव्यक्ति की तलाश कर रहे हैं वह है n - C (0) - C (1) - ... - C (k) th अभिव्यक्ति इसकी लंबाई वर्ग में है।

अब हम बाएं सेगमेंट की लंबाई का पता लगाने के लिए एक समान चाल का उपयोग कर सकते हैं, और फिर उस उपधारा के भीतर रैंक। और फिर उन रैंकों पर पुनरावृत्ति जो हमने पाया!

यह पाया गया कि f (5030, 3749) = 1542317211 पलक झपकते ही।

पायथन, नॉन-कंपेटिंग

def C(n):
    r = 1
    for i in range(n):
        r *= 2*n - i
        r //= i + 1
    return r//(n+1)

def unrank(n):
    if n == 0: return 0

    l = 0
    while C(l) <= n:
        n -= C(l)
        l += 1

    right_l = l - 1
    while right_l and n >= C(l - 1 - right_l) * C(right_l):
        n -= C(l - 1 - right_l) * C(right_l)
        right_l -= 1

    right_num = C(right_l)

    r_rank = n % right_num
    l_rank = n // right_num

    for sz in range(l - 1 - right_l): l_rank += C(sz)
    for sz in range(right_l): r_rank += C(sz)

    return (unrank(l_rank), unrank(r_rank))

def rank(e):
    if e == 0: return 0
    left, right = e

    l = str(e).count("(")
    left_l = str(left).count("(")
    right_l = str(right).count("(")
    right_num = C(right_l)

    n = sum(C(sz) for sz in range(l))
    n += sum(C(sz)*C(l - 1 - sz) for sz in range(left_l))

    n += (rank(left) - sum(C(sz) for sz in range(left_l))) * C(right_l)
    n += rank(right) - sum(C(sz) for sz in range(right_l))

    return n

def f(x, y):
    return rank((unrank(x), unrank(y)))

मुझे पूरा यकीन है कि मैं अनावश्यक संगणना का एक समूह बना रहा हूँ और बहुत से बीच के कदम निकाले जा सकते हैं।

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