সর্বাধিক দক্ষ বাইনারি ফাংশন গণনা করুন


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 এর মতো দেখতে , তবে চ (3, 1) থেকে পৃথক।
কেনেটিএম

2
কিছুক্ষণের মধ্যে এটিই প্রথম চ্যালেঞ্জ যা দক্ষতার সাথে গণনা করতে আমাকে কিছুটা ধাঁধা দেয়। আমি বিশ্বাস করি কাতালান সংখ্যার সাহায্যে কিছু সম্ভব তবে তাত্ক্ষণিকভাবে কোনও সমাধানের কথা ভাবতে পারি না। হুম ...
অরল্প

2
ঠিক আছে, সুতরাং আমি মনে করি না এটি একটি ভাল গল্ফ উত্তর দেবে, তবে আপনি এটি যুক্তিযুক্ত দক্ষ করতে যা করতে পারেন তা হ'ল বারবার কাতালান সংখ্যাগুলি ফাংশন আর্গুমেন্টগুলি থেকে পরের কাতালান সংখ্যার চেয়ে ছোট না হওয়া পর্যন্ত বিয়োগ করে। তারপরে আপনি তাদের অভিব্যক্তিগুলির দৈর্ঘ্যটি খুঁজে পেয়েছেন। তারপরে আপনি ফলাফলটি গণনা করতে, পরিবর্তন সহ, এই কাগজ থেকে র্যাঙ্কিং / আনারঙ্কিং ফাংশনগুলি ব্যবহার করতে পারেন । মাঝখানে কোড বিটগুলি 'বাতিল' করা এবং যুক্তিসঙ্গত মার্জিত সমাধান সন্ধান করা সমস্ত কিছু করার পরে সম্ভবত।
orlp

প্রকৃতপক্ষে, আমার পূর্ববর্তী মন্তব্য থেকে পন্থা কার্যকর হয় না। ((0, (0, (0, 0))), 0)অভিধানের তুলনায় ক্ষুদ্রতর (((0, 0), 0), (0, 0)), তবে পরেরটির বাম হাতটি ছোট থাকে।
orlp

উত্তর:


6

হাস্কেল, ১১০ বাইট

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=<<
পুস্তকে

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. এর বেস কেস পর্যন্ত সমস্তভাবে পুনরাবৃত্তি করে answer এই উত্তরে সি (এন) ফাংশনটি কাতালান সংখ্যাকে বোঝায় ।

গুরুত্বপূর্ণ প্রথম পদক্ষেপটি স্বীকৃতি দিচ্ছে যে সি (0) = 1 দৈর্ঘ্যের শূন্যের মান (যেমন 0 নিজেই), সি (1) = 1 দৈর্ঘ্যের এক মান (যথা f (0, 0)), সি (2) = দৈর্ঘ্যের দুটি মান (চ (0, চ (0, 0)) এবং চ (চ (0, 0), 0))

এর অর্থ হ'ল আমরা যদি নবম এক্সপ্রেশনটির সন্ধান করি এবং আমরা সবচেয়ে বড় কে খুঁজে পাই যে সি (0) + সি (1) + ... + সি (কে) <= n হয় তবে আমরা জানি যে n এর দৈর্ঘ্য কে আছে ।

কিন্তু এখন আমরা চালিয়ে যেতে পারি! কারণ আমরা যে অভিব্যক্তিটির সন্ধান করি তা হ'ল দৈর্ঘ্যের শ্রেণিতে n - C (0) - C (1) - ... - C (k) তম প্রকাশ।

এখন আমরা বাম অংশের দৈর্ঘ্য এবং তারপরের অংশের মধ্যে থাকা র‌্যাঙ্কটি সন্ধান করতে অনুরূপ কৌশল ব্যবহার করতে পারি। এবং তারপরে আমরা যে র‌্যাঙ্কগুলি পেয়েছি তা পুনরুক্তি!

এটি চোখের পলকের মধ্যে 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)))

আমি মোটামুটি নিশ্চিত যে আমি একগুচ্ছ অপ্রয়োজনীয় গণনা করছি এবং অনেকগুলি মধ্য পদক্ষেপ সরানো যেতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.