আমাদের কথা খুঁজে নিন

   

রুট/বিগেইনার লেভেলের প্রোগ্রামিং প্রবলেমস : পর্ব-১ এর সলুশ্যন

তন্ময়-অন-রান.ব্লগস্পট.কম এক্সপ্ল্যানাশেন লিখলাম। কোথাও বুঝতে সমস্যা হলে জানাবেন। ০১. ইনপুট নিতে থাকুন যতক্ষণ না পর্যন্ত ইনপুটটি হয় ‌'৪৫'. _____: ইনপুট হিসেবে পজিটিভ ইন্টিজার দেওয়া হবে। আপনার প্রোগ্রামে কন্টিনিউআসলি ইনপুট দেওয়া হবে। একটা ইনপুট দেওয়া হলে আপনি চেক করবেন যে সেটা ৪৫ কিনা, যদি না হয় তাহলে আবার ইনপুট নিবেন আর হলে 'বাই বাই' ম্যাসেজ শো করে, প্রোগ্রাম শেষ করবেন।

সমাধান: যেহেতু ইনফিনিট নিতে হতে পারে এবং কাজ বলতে শুধু নেওয়া ইনপুটটাকে টেস্ট করা ছাড়া আর কিছু নয় শুধু একটি ব্ল্যাংক হোয়াইল লুপ নিবো। লুপ এর কন্ডিশনের মধ্যেই আমরা ইনপুট নিবো এবং সেই ইনপুটটি কে চেকও করবো, যদি সেটা ৪৫ না হয় তাহলে লুপটা চলবে। যদি ৪৫ হয়ে যায় তাহলে লুপটা ব্রেক করাবো, কেমন? এই লুপ এর বাইরেই আমরা বাই বাই ম্যাসেজ টা রাখবো যাতে লুপ থেকে বের হলে প্রোগ্রাম শেষ হওয়ার আগে ম্যাসেজটা শো করে। ০২. ১ থেকে (১ সহ) ১০০ পর্যন্ত (১০০ সহ) নাম্বারগুলোর মধ্যে ৩ অথবা ৫ দিয়ে নিঃশেষে বিভাজ্য নাম্বার গুলোর যোগফল কত? _____: কোন ইনপুট নেই। প্রোগ্রামটি চালু করলেই তা ১,২,৩,...,১০০ পর্যন্ত নাম্বারগুলোর মধ্যে যে নাম্বারগুলো ৩ অথবা ৫ দিয়ে ভাগ যায় তাদের যোগফল শো করবে।

যেমন ধরুন, ১,২,৩,....,১০ পর্যন্ত নাম্বার গুলোর মধ্যে ৩,৫,৬,৯,১০ নাম্বার গুলোর প্রত্যেকটিই হয় ৩ নয়তো ৫ দিয়ে বিভাজ্য। তাই এক্ষেত্রে আউটপুট হবে, ৩৩. সমাধান: ------------------------------পদ্ধতি ১ (জেনেরাল) এটি সহজ পদ্ধতি। যোগফল রাখার জন্য একটি ভ্যারিয়েবল sum ব্যবহার করবো। যেহেতু বলা হয়েছে, ১ থেকে ১০০, তাই আমরা ৭ নম্বর লাইনের ন্যায় লুপটি চালাবো। একটি নাম্বার দ্বারা আরেকটি নাম্বারকে ভাগ করলে অবশিষ্ট কত থাকে তা জানা যায় mod অপারেশন এর দ্বারা (সি, সি++, জাভা ইত্যাদি ল্যাংগুয়েজে mod কে % চিহ্ন দ্বারা প্রকাশ করা হয়)।

যেমন ১০ % ৩ = ১. যা হোক, যদি বলি x সংখ্যাটি y দ্বারা নিঃশেষে বিভাজ্য হয় তাহলে অবশ্যই x % y = 0. এখানে আমাদের ১ থেকে ১০০ পর্যন্ত এর মধ্যে সেই নম্বরগুলো দরকার যেগুলো হয় ৩ দ্বারা নতুবা ৫ দ্বারা নিঃশেষে বিভাজ্য। আর সেই জন্য ৯ নং লাইনের কন্ডিশনটি বসানো হয়েছে। যদি ট্রু হয় তার মানে বর্তমান i হয় ৩ নতুবা ৫ দ্বারা নিঃশেষে বিভাজ্য। আর তাই এই i কে আমরা sum এর সাথে যোগ করছি (১০ নং লাইনে) ------------------------------পদ্ধতি ২ (একটু ভালো) ওকে, যেহেতু আমরা ১ থেকে ১০০ পর্যন্ত নাম্বার নিয়ে কাজ করছি তাই সহজেই এটা বোঝা যায় যে ৩ দ্বারা নিঃশেষে বিভাজ্য প্রথম সংখ্যাটি ৩ নিজেই, এবং ৫ দ্বারা নিঃশেষে বিভাজ্য প্রথম সংখ্যাটি ৫ নিজেই। তাই এরকম করলে কেমন হয় যে আমরা একটি লুপে i এর মাণ দিবো ৩, প্রতিবারে i এর মাণ ৩ করে বাড়াবো (৭ নং লাইন) এবং লুপের মধ্যে i গুলো যোগ করে একটি ভ্যারিয়েবল যেমন sum_3 তে রাখবো (৮ নং লাইন). এতে করে আমরা ১-১০০ এর মধ্যেকার ৩ দিয়ে নিঃশেষে বিভাজ্য নাম্বার গুলোর যোগফল পেলাম।

এই একই কাজ ৫ এর ক্ষেত্রেও করলাম এবং যোগফল sum_5 এ রাখলাম (১০ ও ১১ নম্বর লাইন). এখন মনে হতে পারে যে এই sum_3 এর সাথে sum_5 কে যোগ করলেই তো হলো, তাই না? কিন্তু না, ১-১০০ এর মধ্যে কিছু কিছু নাম্বার আছে যেগুলোকে ৩ এবং ৫ উভয় দিয়েই ভাগ করা যায়। যেমন ১৫, ৩০ ইত্যাদি। এখানে আমরা আলাদা আলাদা ভাবে যোগফল নেওয়াতে এরকম সংখ্যাগুলো sum_3 এবং sum_5 উভয়ের মধ্যেই ঢুকে গেছে। তাই এগুলোকে বাদ দিতে হবে। এরজন্য আমরা উপরের এই একই প্রসেসর এবার (৩*৫) = ১৫ এর জন্য করবো।

অর্থাৎ সেই নাম্বারগুলোর যোগফল বের করবো যেগুলোকে ১৫ দিয়ে নিঃশেষে ভাগ করা যায় এবং যোগফলকে sum_15 ভ্যারিয়েবল এর মধ্যে রাখছি (লাইন ১৩ এবং ১৪). তাহলে আউটপুট কি হবে? (sum_3 + sum_5) - sum_15 -------পদ্ধতি ৩ (ইফিসিয়েন্ট [আমি এভাবে পারি নাই, নেট থেকে নেওয়া]) অনেক চেষ্টা করলে একটা মেথড ধরতে পারি। অনেক চেষ্টা করলে মেথডটা বুঝতে না পারলেও তার উপর কোড করতে পারি। এই ম্যাথড আমি বুঝি নাই। তবে এটাই ইফিসিয়েন্ট। তাই এখানে দিলাম।

আগের ম্যাথডটার মতই, আলাদা আলাদা ভাবে ৩, ৫ এবং ১৫ এর দ্বারা নিঃশেষে বিভাজ্য যায় ১-১০০ পর্যন্ত এমন নাম্বারগুলোর যোগফল কালেক্ট করতে হবে। কিন্তু লুপ চালাতে হবে না। নীচের ফর্মুলায় ফেলতে হবে। target = সর্বোচ্চ নাম্বার, এক্ষেত্রে ১০০ n = যার দ্বারা ভাগ যায় কিনা টেস্ট করতে চান (এক্ষেত্রে ৩,৫,১৫) তাহলে, n = 3 p = target/n sum_3 = (n*(p*(p+1)))/2 অনুরপ ভাবে, n = 5 p = target/n sum_5 = (n*(p*(p+1)))/2 এবং n = 15 p = target/n sum_15 = (n*(p*(p+1)))/2 আউটপুট = (sum_3 + sum_5) - sum_15 ০৩. ১ থেকে (১ সহ) ১০০০ পর্যন্ত (১০০০ সহ) নাম্বারগুলোর মধ্যে পারফেক্ট নাম্বার গুলো কি কি? _____: পারফেক্ট নাম্বার গুলো সেগুলো যেগুলো তাদেরকে নিঃশেষে ভাগ করতে পারে এমন সব নাম্বারের (সেই নম্বর ছাড়া) যোগফলের সমান। যেমন ১,২,৩,..,১০ নাম্বারগুলোর মধ্যে ৬. ৬ কে ১,২,৩ এই তিনটি নাম্বার দিয়ে নিঃশেষে ভাগ দেওয়া যায় আবার ১+২+৩ = ৬. অতএব ৬ একটি পারফেক্ট নাম্বার।

সমাধান: এই সমাধানটা এই ১-১০০০ রেঞ্জ এর জন্য চললেও বড় রেঞ্জ এ চলবে না। সেক্ষেত্রে অন্যরকম ভাবে লিখতে হবে। যাই হোক, এ ক্ষেত্রে রেঞ্জ যেহেতু ১-১০০০ তাই একটি লুপ চালাচ্ছি ১-১০০০ এর (৭ নং লাইন). পারফেক্ট নাম্বার টেস্ট করার জন্য প্রত্যেকটি নাম্বারের ক্ষেত্রে যেটা করতে হবে সেটা হলো ঐ নাম্বারকে নিঃশেষে ভাগ করতে পারে এমন সব নাম্বার (ঐ নাম্বার ছাড়া) এর যোগফল নিয়ে দেখতে হবে যে যোগফল কি ঐ নাম্বারের সমান কিনা, সমান হলে পারফেক্ট না হলে নাই। এই যোগফল রাখার জন্য y নেওয়া হয়েছে। যেহেতু প্রতিটি i এর জন্য একবার করে কাজ করতে হবে তাই প্রত্যেকবার লুপের শুরুতে y এর মাণ ০ করা হচ্ছে।

এরপর প্রতিটি i এর উপর কাজ করার জন্য ভেতরের লুপটি চালানো হচ্ছে (লাইন ১০). এই লুপটি প্রত্যেকটি i এর জন্যই ১ থেকে শুরু করে i/২ পর্যন্ত চলবে। কারণটা নিজেই একটু বের করার চেষ্টা করুন। অতঃপর দেখা হবে এই j দিয়ে i কে নিঃশেষে ভাগ করা যায় কিনা, গেলে ঐ j কে y এর সাথে যোগ করা হবে। এই লুপ শেষ হলে দেখা হবে y আর i সমান কিনা, হলে পারফেক্ট না হলে নাই, নেক্সট i তে চলে যাবো আমরা। ০৪. নীচের ন্যায় পিরামিড শেপ প্রিন্ট করুন।

_____: এখানে আপনাকে বলে দেওয়া হবে যে কতটি লাইন হবে (পজিটিভ ইন্টিজার নাম্বার), প্রথম লাইন (চূড়াতে থাকবে ^ চিহ্নটি), এর পরের প্রতিটি লাইনের মধ্যের সিম্বলটি হবে | চিহ্নটি, এর বামপাশের গুলো হবে / চিহ্নটি এবং ডান পাশের গুলো হবে \ চিহ্নটি। সমাধান: উপরের পিরামিডের ছবি থেকে কিছু পয়েন্ট বের করে আনুন। শুধু প্রথম লাইনেই ^ চিহ্নটি প্রিন্ট হবে। ১ নং লাইন, ১৪ স্পেস, ১ টা সিম্বল ২ নং লাইন, ১৩ স্পেস, ৩ টা সিম্বল ৩ নং লাইন, ১২ স্পেস, ৫ টা সিম্বল বুঝতে পারছেন নিশ্চয় কে কিভাবে বাড়ছে আর কমছে। ১৫ টি লাইনের জন্য i কে কন্ট্রোলার করে i =১ থেকে ১৫ পর্যন্ত প্রথম লুপ চালানো হয়েছে।

(লাইন ১১) ১৩ নাম্বার লাইনে আছে আরেকটি লুপ যার কাজ স্পেসগুলো প্রিন্ট করা। space নামে একটা ভ্যারিয়েবল নিয়েছি যার মাণ হবে x-1 (লাইন ৮). এক্ষেত্রে space = ১৪. ১৩ নাম্বার লাইনের লুপে যখন i =১ হবে তখন স্পেস প্রিণ্ট হবে ১৪ টি, i =২ হবে যখন তখন space এর মাণ ১ কমে যাবে, space = ১৩, অর্থাৎ ১৩ টি স্পেস প্রিণ্ট হবে। স্পেস প্রিণ্ট করার পর আমাদের নেক্সট কাজ হচ্ছে সিম্বলগুলো প্রিণ্ট করা। এই জন্যই ১৬ নাম্বার লাইনের লুপটি চালানো হয়েছে। দেখুন, ১ নং লাইনে ১ টি সিম্বল ২ নং এ ৩ টি ৩ নং এ ৫ টি অর্থাৎ সিম্বল এর সংখ্যা ১ থেকে শুরু হয়ে ২ করে বাড়ছে।

তাই আমরা শুরুতেই y নামে একটা ভ্যারিয়েবল নিছি যেটার ভ্যালু দিছি ১, অর্থাৎ প্রথম বার ১ টা সিম্বল, দ্বিতীয়বার y এর মাণ ২ বাড়বে মান হবে ৩ অর্থাৎ ৩ টা সিম্বল। কিন্তু সব সিম্বল তো আর একই না। ১৬ নং লাইনের লুপের কন্ট্রোলার j. j এর মাণ যখন ১ তখন প্রিণ্ট হবে প্রথম সিম্বল, আর i এর মাণ ১ নং হওয়া মানে প্রথম লাইন। আর সেই জন্য ১৮ নং লাইনের কন্ডিশনের মাধ্যমে আমরা ^ চিহ্নটি একবার প্রিণ্ট করছি। খেয়াল করুন j এর মাণ প্রতি i এর জন্যই একবার করে ১ হলেও, i এর মাণ আর কখনোই ১ হবে না।

এবার খেয়াল করুন, ১ নম্বর বাদে ২ নম্বর লাইন থেকে যখন i = ২, তখন দ্বিতীয় সিম্বলটি | যখন i = ৩, তখন তৃতীয় সিম্বলটি | ১৬ নং লাইনের লুপে সিম্বলকে প্রিণ্ট করছে j, তাই j এর মাণ যখন i এর সমান হবে তখন | এটি প্রিণ্ট করেছি, i এর চেয়ে ছোট হলে (অর্থাৎ বাম পার্শ্ব) / চিহ্নটি প্রিণ্ট করেছি, i এর চেয়ে বড় হলে (অর্থাৎ ডান পার্শ্ব) \ চিহ্নটি প্রিণ্ট করেছি(লাইন ২০-২৫)। এই স্পেস আর সিম্বল প্রিণ্ট হয়ে গেলে পরের লাইনে যাওয়ার জন্য একটি নিউ লাইন নেওয়া হয়েছে (লাইন ২৭). এরপর পরের i তে যাওয়ার আগে space এর মাণ ১ কমানো হয়েছে এবং সিম্বল এর সংখ্যা বাড়ানোর জন্য y এর মাণ ২ বাড়ানো হয়েছে। ।

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