চারদিক দেখতে রোল!


10

ধরা যাক আপনার একটি 20-পক্ষের ডাই আছে। আপনি শেষ পর্যন্ত সমস্ত 20 টি মানকে রোল করার আগে আপনি সেই ডোলটি শুরু করেন এবং কয়েক ডজন বার এটি রোল করতে হবে। আপনি অবাক হন, সমস্ত 20 টি মান দেখার 50% সুযোগ পাওয়ার আগে আমার কতগুলি রোলগুলির প্রয়োজন? এবং চারপাশে nঘূর্ণায়মান হওয়ার আগে আমাকে কতটা রাইডের মরার রোল দরকার n?

কিছু গবেষণা করার পরে, আপনি খুঁজে পেতে পারেন যে রোলসের পরে সমস্ত মান রোল করার সম্ভাবনা গণনা করার জন্য একটি সূত্র বিদ্যমান ।nr

P(r, n) = n! * S(r, n) / n**r

যেখানে দ্বিতীয় ধরণের স্ট্র্লিং সংখ্যাকেS(a, b) বোঝায় , এন অবজেক্টের একটি সেট (প্রতিটি রোল) কে খালি খালি সাবসেটে (প্রতিটি পাশ) বিভক্ত করার উপায়গুলির সংখ্যা।

আপনি OEIS ক্রমটিও খুঁজে পাবেন , যা আমরা কল করব, যা R(n)সর্বনিম্ন rযেখানে P(r, n)কমপক্ষে 50% রয়েছে তার সাথে মিল রাখে। চ্যালেঞ্জটি হ'ল nএই সিকোয়েন্সের তম শব্দটি যত দ্রুত সম্ভব গণনা করা ।

চ্যালেঞ্জ

  • দেওয়া হয়েছে n, সবচেয়ে ছোট r যেখানে 50 বা এর P(r, n)চেয়ে বড় বা সমান এটি সন্ধান করুন 0.5
  • আপনার কোডটি তাত্ত্বিকভাবে কোনও অ-নেতিবাচক পূর্ণসংখ্যাকে nইনপুট হিসাবে পরিচালনা করতে হবে, তবে আমরা কেবলমাত্র আপনার কোডের সীমাতে পরীক্ষা করব 1 <= n <= 1000000
  • স্কোরিং জন্য, আমরা হতে হবে মোট সময় চালানোর জন্য প্রয়োজনীয় নেওয়া R(n)ইনপুট উপর 1মাধ্যমে 10000
  • আমরা আপনার সমাধানগুলি আমাদের সংস্করণে চলছে দ্বারা ঠিক থাকে তাহলে চেক করবে R(n)আপনার আউটপুট দেখতে যদি P(your_output, n) >= 0.5এবং P(your_output - 1, n) < 0.5, অর্থাত্ যে আপনার আউটপুট আসলে সবচেয়ে ছোট rএকটি প্রদত্ত জন্য n
  • S(a, b)আপনার সমাধানের জন্য আপনি কোনও সংজ্ঞা ব্যবহার করতে পারেন । উইকিপিডিয়ায় বেশ কয়েকটি সংজ্ঞা রয়েছে যা এখানে সহায়ক হতে পারে।
  • আপনি নিজের সমাধানগুলিতে বিল্ট-ইনগুলি ব্যবহার করতে পারেন, যা গণনা করে S(a, b)বা এমনকি P(r, n)সরাসরি গণনা করে এমনগুলিও অন্তর্ভুক্ত।
  • আপনি এক হাজার মান R(n)এবং এক মিলিয়ন স্ট্র্লিং সংখ্যা পর্যন্ত হার্ডকোড করতে পারেন , যদিও এর মধ্যে দুটিও সীমাবদ্ধ নয়, এবং যদি আপনি তাদের উত্থাপন বা হ্রাস করার জন্য দৃ a়প্রত্যয়ী যুক্তি করতে পারেন তবে পরিবর্তন করা যেতে পারে।
  • আপনি প্রতি সম্ভব চেক করতে হবে না rমধ্যে nএবং rআমরা খুঁজছেন, কিন্তু আপনি ক্ষুদ্রতম খোঁজার প্রয়োজনীয়তা না rএবং ঠিক কোন না rযেখানে P(r, n) >= 0.5
  • আপনার প্রোগ্রামটি অবশ্যই এমন একটি ভাষা ব্যবহার করবে যা উইন্ডোজ 10 এ অবাধে চলমান।

কম্পিউটার এর স্পেসিফিকেশনের যে আপনার সমাধানগুলি পরীক্ষা হবে i7 4790k, 8 GB RAMপরীক্ষার জন্য তার কম্পিউটার সরবরাহ করার জন্য @ ডিজেএমসিমেহেমকে ধন্যবাদ জানাই । রেফারেন্সের জন্য আপনার নিজের অফিশিয়াল সময় যুক্ত করতে নির্দ্বিধায় মনে করুন , তবে ডিজে এটি পরীক্ষা করার পরে অফিসিয়াল সময় পরে দেওয়া হবে।

পরীক্ষার মামলা

n       R(n)
1       1
2       2
3       5
4       7
5       10
6       13
20      67       # our 20-sided die
52      225      # how many cards from a huge uniformly random pile until we get a full deck
100     497
366     2294     # number of people for to get 366 distinct birthdays
1000    7274
2000    15934
5000    44418
10000   95768
100000  1187943
1000000 14182022

আপনার যদি কোনও প্রশ্ন বা পরামর্শ থাকে তবে আমাকে জানান। শুভকামনা এবং ভাল অপ্টিমাইজিং!


1
পছন্দ করুন সতর্ক থাকুন জন্য ধন্যবাদ।
শার্লক 9

উত্তর:


7

পাইথন + নুমপি, ৩.৯৯ সেকেন্ড

from __future__ import division
import numpy as np

def rolls(n):
    if n == 1:
        return 1
    r = n * (np.log(n) - np.log(np.log(2)))
    x = np.log1p(np.arange(n) / -n)
    cx = x.cumsum()
    y = cx[:-1] + cx[-2::-1] - cx[-1]
    while True:
        r0 = np.round(r)
        z = np.exp(y + r0 * x[1:])
        z[::2] *= -1
        r = r0 - (z.sum() + 0.5) / z.dot(x[1:])
        if abs(r - r0) < 0.75:
            return np.ceil(r).astype(int)

for n in [1, 2, 3, 4, 5, 6, 20, 52, 100, 366, 1000, 2000, 5000, 10000, 100000, 1000000]:
    print('R({}) = {}'.format(n, rolls(n)))

import timeit
print('Benchmark: {:.2f}s'.format(timeit.timeit(lambda: sum(map(rolls, range(1, 10001))), number=1)))

এটি অনলাইন চেষ্টা করুন!

কিভাবে এটা কাজ করে

এই ব্যবহারের জন্য বদ্ধ-ফর্ম সিরিজ পি ( , এন ), এবং সম্মান সঙ্গে তার ব্যুৎপন্ন , সংখ্যাসূচক স্থিতিশীলতা ও vectorization জন্য পুনর্বিন্যাস জন্য একটি নিউটনের পদ্ধতি অনুসন্ধান করতে R যেমন যে পি ( , এন ) = 0.5, rounding প্রতিটি পদক্ষেপ সামনে একটি পূর্ণসংখ্যা, যতক্ষণ না পদক্ষেপ প্যাচসমূহ r কম 3/4 দ্বারা। একটি ভাল প্রাথমিক অনুমান সহ, এটি সাধারণত মাত্র এক বা দুটি পুনরাবৃত্তি গ্রহণ করে।

x i = লগ (1 - i / n ) = লগ (( এন - আই ) / এন )
সিক্স আই = লগ ( এন ! / (( এন - আমি - 1)! ⋅ n আমি + 1 ) y i = cx i + cx n - i - 2 - cx n - 1 = লগ বিনোম ( n , i + 1) z i = (-1) i + 1 ⋅ বিনম ( n ,আই + 1) ⋅ (( এন - আই - 1) / এন ) আর 1 + ∑ z i = n! ⋅ এস ( আর , এন)


) / এন R = পি ( , এন )
z- র আমিএক্স আমি +1 = (-1) আমি +1 ⋅ binom ( এন , আমি +1) ⋅ (( এন - আমি - 1) / এন ) আর লগ (( এন - আই - 1) / এন)
z ix i + 1 = d / d আর পি ( আর , এন )


1
পুরো উত্তরে দুর্দান্ত কাজ! প্রথমত, আমি বুঝতে পারি যে 0.366512এটি logযুগ যুগ আগে কিছু ছিল । -log(log(2)আমার পরবর্তী পুনরাবৃত্তিতে ব্যবহার করবে । দ্বিতীয়ত, নিউটনের পদ্ধতিটি ব্যবহার করার ধারণাটিও খুব চতুর এবং এটি দেখে আমি আনন্দিত যে এটি এত ভালভাবে কাজ করে। তৃতীয়, আমি প্রায় অবশ্যই চুরি করতে চলেছি exp(log(binom(n, i+1)) + r * log((n-i-1)/n)): পি কুডোস দুর্দান্ত উত্তর! : ডি
শার্লক

1
আমি অফিসিয়াল সময় যোগ করেছি! সুন্দর উত্তর বিটিডাব্লু :)
জেমস

2
আমি সত্যি বিভ্রান্ত. আমি numpyআমদানি পরিবর্তন করেছি from numpy import *এবং কোনও কারণে সময়টি মূলত 0 এ নেমে গেছে ... এটি অনলাইনে চেষ্টা করবেন ?
notjagan

@ নটজাগান ক্যাশে হিট হতে পারে?
NoOneIs এখানে

1
আমি বেশ কয়েকটি জিনিসের জন্য ক্ষমা চাইতে চাই: 1) আমি যখন উন্নতিগুলি অনুসন্ধান করার চেষ্টা করেছি তখন আপনার উত্তর সম্পর্কে আমার চুরির লেখা; 2) সঠিকভাবে এটির মালিক না এবং কেবল আমার উত্তর ঠিক করার চেষ্টা করছি; 3) এই ক্ষমা প্রার্থনাটি এত দীর্ঘ সময় নিয়েছে। আমি এতটাই হতবাক হয়ে গিয়েছিলাম যে প্রথমে আমি এই চ্যালেঞ্জটি ত্যাগ করেছি। পুনঃস্থাপনের একটি ছোট্ট প্রচেষ্টাতে, আমি মনে করি এটি আপনাকে ন্যায্য বলে মনে হচ্ছে যে এই উত্তরটিতে আমার মূল উন্নতি নিউটনের পদ্ধতি থেকে বাড়তিকরণের দিকে পরিবর্তিত হয়েছিল r, কারণ আপনার প্রাথমিক অনুমান ইতিমধ্যে বেশ ভাল। আশা করি আপনাকে আরও একবার পিপিসিজিতে দেখব এবং সব কিছুর জন্য দুঃখিত sorry
শার্লক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.