ফিবোনাচি সিকোয়েন্সের দক্ষ পাইথোনিক জেনারেটর
এই সিক্যুয়েন্সের সংক্ষিপ্ততম পাইথোনিক প্রজন্মকে পাওয়ার চেষ্টা করার সময় আমি এই প্রশ্নটি পেয়েছি (পরে বুঝতে পেরে আমি পাইথন বর্ধনের প্রস্তাবতে একই রকম দেখতে পেয়েছি ), এবং আমার নির্দিষ্ট সমাধান নিয়ে অন্য কেউ আসছেন তা আমি লক্ষ্য করি নি (যদিও শীর্ষের উত্তরটি কাছাকাছি হলেও কম মার্জিত হয়), তাই এখানে প্রথম পুনরাবৃত্তির বর্ণনা দেওয়ার মতামত দেওয়া হয়েছে, কারণ আমি মনে করি এটি পাঠকদের বুঝতে সহায়তা করতে পারে:
def fib():
a, b = 0, 1
while True: # First iteration:
yield a # yield 0 to start with and then
a, b = b, a + b # a will now be 1, and b will also be 1, (0 + 1)
এবং ব্যবহার:
for index, fibonacci_number in zip(range(10), fib()):
print('{i:3}: {f:3}'.format(i=index, f=fibonacci_number))
কপি করে প্রিন্ট:
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
10: 55
(স্বীকৃতিপ্রদান উদ্দেশ্যে, আমি সম্প্রতি একটি লক্ষ্য অনুরূপ বাস্তবায়ন মডিউল উপর পাইথন ডকুমেন্টেশনে, এমনকি ভেরিয়েবল ব্যবহার a
এবং b
, আমি এখন যা প্রত্যাহার এই উত্তরটি লেখার আগে দেখা হচ্ছে। কিন্তু আমি এই উত্তর ভাষা ভালো ব্যবহার প্রমান মনে হয়।)
পুনরাবৃত্তির সাথে সংজ্ঞায়িত বাস্তবায়ন
পূর্ণসংখ্যা ক্রম অনলাইন এনসাইক্লোপিডিয়া ফিবানচি সিকোয়েন্স যাও recursively সংজ্ঞায়িত হিসাবে
F (n) = F (n-1) + F (n-2) এর সাথে F (0) = 0 এবং F (1) = 1
পাইথনে এটিকে পুনরাবৃত্তভাবে সংজ্ঞায়িত করা নিম্নলিখিতভাবে করা যেতে পারে:
def rec_fib(n):
'''inefficient recursive function as defined, returns Fibonacci number'''
if n > 1:
return rec_fib(n-1) + rec_fib(n-2)
return n
তবে গাণিতিক সংজ্ঞাটির এই সঠিক প্রতিনিধিত্ব 30 এর চেয়ে বেশি সংখ্যার জন্য অবিশ্বাস্যভাবে অক্ষম, কারণ প্রতিটি সংখ্যা গণনা করা হচ্ছে তার নীচের প্রতিটি সংখ্যার জন্যও গণনা করতে হবে। নিম্নলিখিতটি ব্যবহার করে আপনি কতটা ধীর গতিতে তা প্রদর্শন করতে পারেন:
for i in range(40):
print(i, rec_fib(i))
দক্ষতার জন্য স্মরণীয় পুনরাবৃত্তি
গতি উন্নত করার জন্য এটি স্মৃতিচারণ করা যেতে পারে (এই উদাহরণটি এই ফাংশনটি গ্রহণ করে যে একটি ডিফল্ট কীওয়ার্ড আর্গুমেন্ট একই সময়ে প্রতিটি ফাংশন বলা হয়, তবে সাধারণত আপনি ঠিক এই কারণে কোনও পরিবর্তনীয় ডিফল্ট যুক্তি ব্যবহার করবেন না):
def mem_fib(n, _cache={}):
'''efficiently memoized recursive function, returns a Fibonacci number'''
if n in _cache:
return _cache[n]
elif n > 1:
return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
return n
আপনি দেখতে পাবেন মেমোজাইজড সংস্করণটি আরও দ্রুত এবং কফির জন্য উঠে পড়ার চিন্তাভাবনা করার আগে দ্রুত আপনার সর্বাধিক পুনরাবৃত্তির গভীরতা ছাড়িয়ে যাবে। এটি দেখতে আপনি দেখতে পারবেন যে এটি দৃশ্যমানভাবে কতটা দ্রুত:
for i in range(40):
print(i, mem_fib(i))
(মনে হচ্ছে আমরা কেবল নীচের কাজটি করতে পারি, তবে এটি আসলে আমাদের ক্যাশে সুবিধা নিতে দেয় না, কারণ সেটডিফল্ট বলার আগে এটি নিজেকে কল করে))
def mem_fib(n, _cache={}):
'''don't do this'''
if n > 1:
return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
return n
পুনরাবৃত্তভাবে সংজ্ঞায়িত জেনারেটর:
যেহেতু আমি হাস্কেল শিখছি, আমি হাসকেলে এই বাস্তবায়নটি দেখতে পেয়েছি:
fib@(0:tfib) = 0:1: zipWith (+) fib tfib
এই মুহুর্তে পাইথনে আমি এর নিকটতম স্থানটি পেতে পারি বলে মনে করি:
from itertools import tee
def fib():
yield 0
yield 1
# tee required, else with two fib()'s algorithm becomes quadratic
f, tf = tee(fib())
next(tf)
for a, b in zip(f, tf):
yield a + b
এটি এটি দেখায়:
[f for _, f in zip(range(999), fib())]
যদিও এটি কেবল পুনরাবৃত্তি সীমাতে যেতে পারে। সাধারণত, 1000, যেখানে হাস্কেল সংস্করণটি 100 লক্ষ লক্ষ পর্যন্ত যেতে পারে, যদিও এটি করতে আমার ল্যাপটপের সমস্ত 8 জিবি মেমরি ব্যবহার করে:
> length $ take 100000000 fib
100000000
নবম ফিবোনাচি নম্বর পেতে পুনরাবৃত্তি গ্রহণ করা
একজন মন্তব্যকারী জিজ্ঞাসা করেছেন:
পুনরাবৃত্তির উপর ভিত্তি করে ফাইব () ফাংশনের জন্য প্রশ্ন: আপনি যদি নবম পেতে চান, উদাহরণস্বরূপ দশম ফাইব সংখ্যা?
ইটারটুলস ডকুমেন্টেশনের এটির জন্য একটি রেসিপি রয়েছে:
from itertools import islice
def nth(iterable, n, default=None):
"Returns the nth item or a default value"
return next(islice(iterable, n, None), default)
এবং এখন:
>>> nth(fib(), 10)
55