প্রথমে আমরা একটা সমস্যা ঠিক করি যেটা আমরা সমাধান করব সি তে প্রোগ্রাম লিখে।প্রাইম নাম্বার বা মৌলিক সংখ্যার ব্যাপারে আমরা তো মনে হয় সবাই জানি, তাইনা ? যেসব সংখ্যাকে প্রাইম ফ্যাক্টরাইজ করা যায় না সেগুলোই প্রাইম নাম্বার।সোজা বাংলায় বলতে গেলে যে সংখ্যাকে ১ এবং ঐ সংখ্যা ছাড়া অন্য কোন সংখ্যা দিয়ে ভাগ করা যায়না তাকে আমরা প্রাইম নাম্বার বা মৌলিক সংখ্যা বলি।আজ আমাদের সমস্যাটা হবে,আমরা একটা নাম্বার ইনপুট নিব।সেটা প্রাইম কিনা সেটা আমরা পরীক্ষা করে দেখব।যদি প্রাইম হয় তাহলে আমরা প্রিন্ট করব "The Number is Prime" আর যদি প্রাইম না হয় তাহলে "The Number is Not Prime" এই কথাটা প্রিন্ট করে দেখাব কনসোল স্ক্রীনে।
এখন একটু চিন্তা করি যে আজকের সমস্যার সমাধান আমরা করব কিভাবে।কাজ আমাদের তিনটা।
আসলে প্রোগ্রামিংয়ে এটা খুব ভালো একটা স্ট্রাটেজি।আমরা যখনই কোন সমস্যা সমাধান করার কথা ভাববো,আগে আমরা ঐ সমস্যাটাকে অনেকগুলো ছোট ছোট সমস্যায় ভাগ করে ফেলব মনে মনে।কাগজে কলমে এটা করা বেটার প্র্যাকটিস।এরপর ঐ ছোট ছোট সমস্যাগুলো একটা একটা নিয়ে সেটা কিভাবে সমাধান করব সেটা চিন্তা করে বের করব।আমাদের এই ছোট ছোট সমস্যাগুলোর সমাধানগুলোকে একত্র করলে যেটা হবে সেটাই আমাদের মূল সমস্যার সমাধান।এই আইডিয়া ইমপ্লিমেন্ট করার জন্য সি খুবই ভালো একটা প্রোগ্রামিং ল্যাংগুয়েজ।এই আইডিয়াটাকে বলা হয় মডিউলারিটি।
যাহোক, ইনপুট তো আমরা নিতেই পারি।আমরা এই সিরিজে আগের পোস্টগুলোতে সেটা শিখে ফেলেছি সফলভাবেই।এখন আমরা দেখব কিভাবে প্রাইম নাম্বার চেক করতে হয়।এবার ফিরে যাই অংকের বইতে।কি ছিল যেন ব্যাপারটা ? যে সংখ্যাকে ১ এবং ঐ সংখ্যা ছাড়া অন্য কোন সংখ্যা দিয়ে ভাগ করা যায়না সেটা প্রাইম সংখ্যা,তাইনা ? হ্যা, তাহলে আমরা যদি ১ থেকে ঐ সংখ্যার মাঝে এমন একটা সংখ্যা বের করতে পারি যেটা দিয়ে আমাদের ইনপুট নেওয়া সংখ্যাকে ভাগ করা যায় তাহলে নিশ্চিতভাবে সেটা প্রাইম না।আর এমন কোন সংখ্যা যদি না থাকে তাহলে আমরা সিওর থাকতে পারি যে আমাদের ইনপুট নেওয়া সংখ্যাটা ১ ও সে নিজে ছাড়া অন্য কোন সংখ্যা দ্বারা নি:শেষে বিভাজ্য নয়,অর্থাৎ কিনা সে প্রাইম নাম্বার।
এখন এটা কিভাবে প্রোগ্রাম করা যায় দেখি।আমরা মাঝের কোন একটা নাম্বার বের করার কথা বলছিলাম।সেই নাম্বারটা সর্বোচ্চ কত হতে পারে ? একটু ভাবলে মনে হয় আমরা বলতে পারব,সেটা আমাদের ইনপুটের অর্ধেক হবে যদি কিনা জোড় সংখ্যা হয় আর বিজোড় হলে সেই সংখ্যাটা হবে অর্ধেকের চেয়েও ছোট কোন সংখ্যা।কাজেই এমন একটা সংখ্যা খুঁজে পেতে আমাদেরকে ইনপুট নাম্বারের অর্ধেক পর্যন্ত খুঁজলেই যথেষ্ট হবে।এবার একটু চিন্তা করি।ধরলাম,আমরা ইনপুট দিলাম ৫০১।এখন ২ থেকে শুরু করে ২৫০ পর্যন্ত প্রতিবার আমাদের চেক করা লাগবে যে সেটা দিয়ে ৫০১ কে ভাগ করা যায় কিনা।তাহলে আমরা যদি প্রতিটা নাম্বার দিয়েই চেক করি তাহলে তো আমাদেরকে এই ইনপুটের জন্য ২৪৯ লাইন লিখতে হবে মিনিমাম তাও যদি কিনা প্রতিবার চেক করতে এক লাইন লিখতে হয়।তাইনা ? আর ইনপুট যদি বিরাট কোন সংখ্যা হয় তখন ??? কোড লিখতে লিখতে পাগল হওয়ার যোগাড় হবে আর কি।
কাজেই এই মুহুর্তে আমরা এমন কিছু একটার দরকার অনুভব করছি যেটা দিয়ে একই কাজ বারবার করিয়ে নেওয়া যায়।হ্যাঁ, এটাকে লুপ বলা হয়।লুপ বেশ কয়েক রকম আছে সি তে।আজ আমরা সেগুলোর ব্যবহার শিখে ফেলার চেস্টা করব।
একটা লুপ চালাতে হলে আমাদের তিনটা জিনিস লাগবে।সেগুলো হল:
এবার দেখি সি তে কিভাবে এটা আমরা লিখব। প্রথমেই আসি For Loop এ।
for(expression 1 ; expression 2 ; expression 3 ) { Do What is to be done..... }
যেকোন লুপ চালাতে হলে আমাদের একটা লুপ কন্ট্রোলিং ভ্যারিয়েবল লাগবে।সেটা আমরা প্রথমে যখন ভ্যারিয়েবল ডিক্লেয়ার করি তখন করতে পারি আবার লুপের ব্রাকেটের ভিতরও ডিক্লেয়ার করতে পারি,আমাদের ইচ্ছা।এক্সপ্রেশন ১ এ আমরা লুপ যেখান থেকে শুরু হবে সেটা লুপ লুপ কন্ট্রোলিং ভ্যারিয়েবলকে দিয়ে দিব।মাঝের এক্সপ্রেশনে অর্থাৎ ২ তে আমরা চেক করব যে আমরা লুপে ঢুকব নাকি লুপ ছেড়ে বেরিয়ে যাব।আর শেষের এক্সপ্রেশনে আমরা লুপ কন্ট্রোলিং ভ্যারিয়েবলকে আমাদের দরকারমত বাড়াব অথবা কমাব।তবে অবশ্যই এটা একটা জেনারেল আইডিয়া যেটা আমাদেরকে সাধারন কাজকর্ম করতে কাজে লাগবে।মজার ব্যাপার হল লুপের এই ব্রাকেটের ভিতর আমরা যেকোন এক্সপ্রেশন লিখতে পারি, হ্যাঁ যেকোন এক্সপ্রেশন :), যেটা আমাদের উদ্দেশ্য হাসিল করবে।যদি কেউ ডেনিস রিচির বইটা পড়েন তাহলে অন্য বইয়ের সাথে এর কোডগুলো মেলাতে কস্ট হবে এমন উদ্ভট কোড লেখা।তবে আমার শেষ কথাটা বুঝতে পারবেন।
২ নং এক্সপ্রেশনটা কিন্তু খুবই গুরুত্বপূর্ণ।কেন ?খেয়াল করুন,আসলে সেটা আপনার লুপটাকে নিয়ন্ত্রন করছে।আপনি যদি ওখানে ভুল কিছু লিখে রাখেন তাহলে বড় সমস্যা হতে পারে।যেমন,ধরুন আপনি ওখানে কিছু লিখলেন না।কি হবে বলুন তো একটু ভেবে ? প্রতিবার যখন লুপ ঘুরবে তখন কন্ডিশন চেক করতে গিয়ে যখন কিছু পাবে না তখন সে লুপে ঢুকবে ও কাজ শেষে বেরিয়ে আবার চেক করবে,আবার ঢুকবে।এভাবে অনন্তকাল ঐ লুপ চলতে থাকবে।
লুপ যখন এক্সিকিউট হবে তখন সেটা হবে এভাবে।প্রথমে এক্সিকিউট হবে এক্সপ্রেশন ১ এবং এটাকে আর কখনও প্রোগ্রাম দেখবে না, এই একবারই মাত্র।এরপর সে এক্সপ্রেশন ২ এক্সিকিউট করে সিদ্ধান্ত নেবে, সে লুপের ভিতর ঢুকবে কি না।যদি ঢোকে ভিতরের কাজ সেরে সে যাবে এক্সপ্রেশন ৩ এ।সেখানে i মানে লুপ কন্ট্রোল ভ্যারিয়েবলের মান এক বাড়িয়ে নিয়ে যে আবার যাবে এক্সপ্রেশন ২ তে।সেখানে লুপে ঢোকার সিদ্ধান্ত নিয়ে আবার আগের মত ঢুকে কাজ সেরে ৩ এ ফিরবে,ভ্যালু বাড়াবে,বাড়িয়ে ২ তে যাবে।এভাবে চলতে চলতে যখন ২ এর কন্ডিশন মিথ্যা হয়ে যাবে তখন সে আর লুপে ঢুকবে না।লুপ থেকে বেরিয়ে পরের স্টেটমেন্টে চলে যাবে।
int isprime = 1; for(i = 2 ; i<= input/2 ; i++) { if((input % i)==0) { isprime = 0; } }
এখন আমরা আমাদের সমস্যা সমাধানে নজর দিই।চলে যাই উপরে যেখানে লুপ চালানোর জন্য যে তিনটা জিনিস লাগবে সেটা বলেছি।ধরলাম আমাদের লুপ কন্ট্রোলিং ভ্যারিয়েবল হল ইন্টিজার i ।তাহলে আমরা i এর ভিতর ২ ভ্যালুটা রেখে লুপ শুরু করব কারন আমাদের ২ থেকে শুরু করতে হবে (১ তো প্রাইম না), আগেই বলেছি।এরপর গুরুত্বপূর্ণ এক্সপ্রেশনটা।আমরা কতদূর যাব ?? ইনপুটের অর্ধেক।কাজেই i যতক্ষন ইনপুটের অর্ধেকের সমান অথবা ছোট ততক্ষনই আমরা লুপের ভিতর ঢুকব,তাছাড়া নয়।আর i এর ভ্যালু ৩ নং এক্সপ্রেশনে এক করে বাড়াব অর্থাৎ সামনের নাম্বারে যাব।আমাদের সমস্যার জন্য এক্সিকিউশনটা এমন।
এবার আসি লুপের ভিতরের অংশে।এখানে আমাদের দেখতে হবে আমরা যে নাম্বারটা নিয়ে এখন কাজ করছি ( i ) সেটা দিয়ে ইনপুটকে ভাগ করা যায় কিনা।আমরা ভাগ করব না কারন ইন্টিজার ডিভিশন করলে একটা ইন্টিজারই আউটপুট আসে।আমরা মডুলাস অপারেটর ব্যবহার করব।কোন নাম্বারকে যদি অন্য কোন নাম্বার দিয়ে মড করা হয় তাহলে ভাগশেষটা আমরা পাই।এই ভাগশেষ যদি শুন্য হয় তাহলে বোঝাই যায়, যাকে মড করেছি সেই সংখ্যাটা যেটা দিয়ে আমরা মড করলাম সেটা দ্বারা নি:শেষে বিভাজ্য।কাজেই কোথাও যদি i এর কোন ভ্যালুর জন্য এই ভাগশেষ শুন্য হয় তবে আমরা জেনে গেলাম ইনপুট নাম্বারটি প্রাইম নয়,যখন জেনেই গেলাম তাহলে তো আর লুপ চালানোর দরকার নেই।তাই লুপ ব্রেক করে বেরিয়ে এলাম।আর যদি পুরো লুপ শেষ করার পরও এমন কোন সংখ্যা না পাওয়া যায় তাহলে ইনপুট প্রাইম হবে,বোঝাই যাচ্ছে।
এই isprime ভ্যারিয়েবল দিয়ে আমরা লুপ শেষে বুঝতে পারছি যে ইনপুট নাম্বারটা প্রাইম কিনা।শুরুতে এটাতে এক দিয়ে মানে ইনপুটকে প্রাইম ধরে আমরা শুরু করছি।যদি লুপের ভিতর ধরা পড়ে এটা প্রাইম না তাহলে isprime কে আমরা জিরো করে দিচ্ছি যার অর্থ ইনপুট প্রাইম নয়।আর পুরো লুপ শেষ করার পরও ওটার ভ্যালু অপরিবর্তিত থাকে তাহলে ইনপুট নাম্বারটা প্রাইম।
while(condition) { Do What is to be done..... }
while লুপ হল সি তে আরেক প্রকারের লুপ।এটা নিয়ে মাথা খারাপ করার কোনই যুক্তি নেই।সেজন্য আমরা একটা বাংলা বুদ্ধির 🙂 সাহায্য নেব।সেটা বলছি এখন।এখানে কাজ আমাদের একই, পার্থক্য শুধু সিনট্যাক্সে।কাজেই For লুপ যেভাবে এক্সিকিউট হয় ওভাবে জাস্ট আমরা আমাদের কোডকে while লুপের মাধ্যমে একটু সাজিয়ে লিখব।তবে সাজাই।এক্সপ্রেশন ১ কে while লুপের আগে লিখে সেমিকোলন দিয়ে স্টেটমেন্ট বানিয়ে দিই।এরপর এক্সপ্রেশন ২ কে while এর পরের কন্ডিশনের ওখানে বসাই।এরপর while লুপের ভিতর ঢুকে For লুপের ভিতরে যে কাজের কোডটুকু ছিল ওটা কপি করে দিই।তারপর লুপের ভিতরের শেষ স্টেটমেন্ট বানিয়ে দিই আমাদের আগের এক্সপ্রেশন ৩ কে।কাজ শেষ।For লুপ while লুপ হয়ে গেল।
isprime = 1; i = 2; while(i<=input/2) { if((input % i)==0) { isprime = 0; } i++; }
এখন এই isprime ভ্যারিয়েবলটার ভ্যালু অনুযায়ী গত পোস্টের টপিক "কনট্রোল ফ্লো" ব্যবহার করে আউটপুট প্রিন্ট করার দায়িত্বটা আপনাদের হাতে দিয়ে আজকের পোস্ট শেষ করলাম।ভালো থাকুন সবাই 🙂
আমি অয়ন। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 13 বছর 3 মাস যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 6 টি টিউন ও 56 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 0 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।
আমি অয়ন।ব্লগিং করতে পছন্দ করি সত্যি কিন্তু আমি টেক ব্লগার নই।যেহেতু এটা টেক ব্লগ তাই আমাকে চেস্টা করতে হবে টেক ব্লগারের অভিনয় করার।এই মুহূর্তে ঠিক জানিনা কতটুকু সফল অভিনয় করতে পারব :)।পড়াশোনা আপাতত বুয়েটের সিএসই ডিপার্টমেন্টে,ফাইনাল ইয়ার।আর বেশিদিন হয়তো ছাত্র থাকা হবে না,মাত্র এক বছর কিন্তু ছাত্র হয়ে থাকতে পারলেই...
C জানার আমার ব্যাপক আগ্রহ। আপনার টিউন দেখে মুগ্ধ হলাম। আগে আপনার করা ১-৩ পর্ব গুলার টিউন গুলা পড়ে আসি তারপর এসে এটা পরবো। তার পর কেমন হোল জানবো… চালিয়ে যান। ধন্যবাদ 🙂