এই প্রোগ্রামটি কি প্রতিটি পূর্ণসংখ্যার জন্য সমাপ্ত হবে?


14

গেট প্রস্তুতির একটি পার্ট টেস্টে একটি প্রশ্ন ছিল:

f(n):
     if n is even: f(n) = n/2
     else f(n) = f(f(n-1))

আমি উত্তর দিয়েছি "এটি সমস্ত সংখ্যার জন্য সমাপ্ত হবে", এমনকি কিছু নেতিবাচক পূর্ণসংখ্যার জন্যও এটি স্ট্যাক ওভারফ্লো ত্রুটি হিসাবে শেষ হবে ।

তবে আমার বন্ধু এই কথাটি অস্বীকার করেছে যেহেতু এটি কোড এবং কেবলমাত্র সিউডোকোড প্রয়োগ করা হয়নি তাই কিছু নেতিবাচক পূর্ণসংখ্যার ক্ষেত্রে এটি অসীম পুনরাবৃত্তি হবে।

কোন উত্তরটি সঠিক এবং কেন?


8
এটি এন = -1 এর জন্য শেষ হয় না। এই ধরনের ক্ষেত্রে বেশিরভাগ তাত্ত্বিক সীমা বিবেচনা করা হয়।
দীপ জোশী

9
যদি স্ট্যাক ওভারফ্লো সমাপ্তি হিসাবে বিবেচনা করা হয়, তবে সমস্ত প্রোগ্রাম সমাপ্ত হবে এবং এটি এই প্রশ্নের উদ্দেশ্যকে পরাস্ত করবে ...
xuq01

10
@ xuq01 while (true);সমাপ্ত হবে না এবং, বুদ্ধিমান কিছুতেই স্ট্যাকের ওভারফ্লো হতে পারে না।
ট্রিপহাউন্ড

3
@leftaroundabout আমি সম্ভবত "ব্যবহার করেছেন করা উচিত নয় কিছু যুক্তিসম্মত উপর " কারণ এটি একটি সম্পূর্ণ ভিন্ন স্তর "-এর যুক্তিসম্মত " ... spotting এবং লেজ পুনরাবৃত্তির বাস্তবায়ন করছে চমৎকার (অথবা এমনকি যুক্তিসম্মত ), কিন্তু তাই করছেন না শুধুমাত্র সামান্য "হয় যুক্তিসম্মত না "। যে কোনও কিছু যে কোনও স্ট্যাক while(true);ব্যবহার করে এমনভাবে বাস্তবায়িত হয়েছিল তা অবশ্যই বোধগম্য নয় । মুল বক্তব্যটি হ'ল যদি না আপনি ইচ্ছাকৃতভাবে বিশ্রী হওয়ার পথে চলে যান তবে স্ট্যাকের ওভারফ্লো প্রবাহকে শেষ করবে না এবং ট্রিগার করবে না। while(true);
ট্রিপহাউন্ড

14
@ xuq01 আমি মনে করি না "মহাবিশ্বের ধ্বংস" থামানো সমস্যার সমাধান হিসাবে গণ্য।
ট্রিপহাউন্ড

উত্তর:


49

সঠিক উত্তরটি হ'ল এই ফাংশনটি সমস্ত পূর্ণসংখ্যার জন্য শেষ হয় না (বিশেষত, এটি -1-এ শেষ হয় না)। আপনার বন্ধুটি উল্লেখ করে সঠিক যে এটি সিউডোকোড এবং সিউডোকোড কোনও স্ট্যাকের ওভারফ্লোতে শেষ হচ্ছে না। সিউডোকোড আনুষ্ঠানিকভাবে সংজ্ঞায়িত করা হয় নি, তবে ধারণাটি হ'ল টিনে যা বলা আছে তা তাই করে। কোডটি যদি "স্ট্যাক ওভারফ্লো ত্রুটির সাথে সমাপ্তি" না বলে তবে স্ট্যাকের ওভারফ্লো ত্রুটি নেই।

এমনকি যদি এটি একটি আসল প্রোগ্রামিং ভাষা ছিল তবে সঠিক উত্তরটি এখনও "সমাপ্ত হবে না" হবে যদি না কোনও স্ট্যাকের ব্যবহার ভাষার সংজ্ঞাটির অংশ না হয়। বেশিরভাগ ভাষাগুলি এমন প্রোগ্রামগুলির আচরণ নির্দিষ্ট করে না যা স্ট্যাককে উপচে ফেলতে পারে, কারণ কোনও প্রোগ্রাম কতটা স্ট্যাক ব্যবহার করবে তা সঠিকভাবে জানা মুশকিল।

যদি কোনও সত্যিকারের দোভাষী বা সংকলক কোডটি চালনা করার কারণে অনেকগুলি ভাষায় স্ট্যাকের ওভারফ্লো হয়, তবে এটি ভাষার আনুষ্ঠানিক শব্দার্থবিদ্যা এবং বাস্তবায়নের মধ্যে একটি তাত্পর্য। এটি সাধারণত বোঝা যায় যে কোনও ভাষার বাস্তবায়ন কেবলমাত্র সীমাবদ্ধ স্মৃতিযুক্ত একটি কংক্রিট কম্পিউটারে যা করা সম্ভব will যদি প্রোগ্রামটি স্ট্যাকের ওভারফ্লোতে মারা যায়, আপনার মনে হচ্ছে একটি বড় কম্পিউটার কেনা উচিত, সেই সমস্ত স্মৃতি সমর্থন করার জন্য প্রয়োজন হলে সিস্টেমটি পুনরায় কম্পাইল করুন এবং আবার চেষ্টা করুন। প্রোগ্রামটি যদি অবসানহীন হয় তবে আপনার চিরকাল এটি চালিয়ে যেতে হতে পারে।

এমনকি কোনও প্রোগ্রাম স্ট্যাককে উপচে ফেলবে বা করবে না তা সঠিকভাবে সংজ্ঞায়িত হয় না, যেহেতু টেল কল অপটিমাইজেশন এবং মেমোয়েজেশন এর মতো কিছু অপ্টিমাইজেশন ধ্রুবক-সীমাবদ্ধ স্ট্যাক স্পেসে ফাংশন কলগুলির একটি অসীম চেইনকে অনুমতি দিতে পারে। কিছু ভাষার স্পেসিফিকেশন এমনকি ম্যান্ডেট দেয় যে বাস্তবায়নগুলি সম্ভব হলে লেজ কল অপ্টিমাইজেশন সম্পাদন করে (এটি কার্যকরী প্রোগ্রামিং ভাষাগুলিতে সাধারণ)। এই ফাংশনটির জন্য, f(-1)প্রসারিত হয় f(f(-2)); বহিরাগত কলটি fএকটি লেজ কল তাই এটি স্ট্যাকের উপরে কোনও কিছুই চাপায় না, সুতরাং কেবল f(-2)স্ট্যাকের উপরে চলে যায় এবং এটি ফিরে আসে -1, তাই স্ট্যাকটি একই অবস্থায় ফিরে আসে যেখানে এটি শুরুতে ছিল। সুতরাং টেল কল অপ্টিমাইজেশন f(-1)ধ্রুবক স্মৃতিতে চিরকাল লুপ করে।


3
উদাহরণস্বরূপ, যেখানে কোনও প্রোগ্রামিং ভাষার অনূদিত কোডটি কোনও স্ট্যাকের ওভারফ্লোতে নয় ফলাফল হ্যাস্কেল। এটি কেবল অনির্দিষ্টকালের জন্য লুপ করে:let f :: Int -> Int; f n = if even n then n `div` 2 else f (f (n - 1)) in f (-1)
জোল

5

আমরা যদি এটি সি ভাষার পরিপ্রেক্ষিতে দেখে থাকি তবে একটি বাস্তবায়ন কোডের সাথে কোড প্রতিস্থাপনের জন্য মুক্ত যা সমস্ত ক্ষেত্রে একই ফলাফল উত্পন্ন করে যেখানে মূল অনির্ধারিত আচরণকে আহ্বান করে না। সুতরাং এটি প্রতিস্থাপন করতে পারেন

f(n):
   if n is even: f(n) = n/2
   else f(n) = f(f(n-1))

সঙ্গে

f(n):
   if n is even: f(n) = n/2
   else f(n) = f((n-1) / 2)

এখন প্রয়োগটি লেজ পুনরাবৃত্তি প্রয়োগ করার অনুমতি দেওয়া হয়েছে:

f(n):
   while n is not even do n = (n-1) / 2
   f(n) = n/2

এবং এই যদি চিরকালের জন্য লুপ হয় কেবলমাত্র এবং যদি n = -1 থাকে।


আমি মনে করি, সি তে, অনুরোধটি f(-1)অপরিজ্ঞাত আচরণ (বাস্তবায়ন ধরে নিতে পারে যে প্রতিটি থ্রেডটি এই ফাংশনটি না করে এমন একটি সংক্ষিপ্ত তালিকায় অন্যথায় কিছুটা বন্ধ করে দেয় বা অন্য কিছু করে), তাই সংকলক আসলে যা চায় তাতে কিছু করতে পারে মামলা!
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.