অধ্যায় চার : লুপ


আমাদেরকে অনেক সময় একই কাজ বারবার করতে হয় । এর মধ্যে কিছু কিছু কাজ অত্যন্ত বিরক্তিকর । ধরো তোমাকে এক থেকে দশ পর্যন্ত সংখ্যাগুলো প্রিন্ট করতে বলা হলো । তাহলে কি করতে ? নিচের মত করে লিখতে :

 printf("1\n");
 printf("2\n");
 printf("3\n");
 //...এভাবে দশ বার
কিংবা এভাবে
 printf("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n
 ");

নয়তো এভাবে :

 int n = 1;
 printf("%d\n", n);
 n = n + 1;
 printf("%d\n", n);
 n = n + 1;
 printf("%d\n", n);
 //...এভাবে দশবার

 int n = 1;
 printf("%d\n", n);
 printf("%d\n", n++);
 printf("%d\n", n++);
 //...এভাবে দশবার (n++,n=n+1, n += 1 
 একই ব্যাপার)

কিন্তু এক থেকে দশ পর্যন্ত প্রিন্ট করতে না বলে যদি এক থেকে দশ হাজার কিংবা দশ লাখ পর্যন্ত প্রিন্ট করতে বলা হতো (!) তাহলে কি করতে ? প্রোগ্রামিং করা ছেড়ে দিতে নাকি পালিয়ে যেতে ?

কতই না ভালো হতো বলো যদি প্রোগ্রামে এমন একটা কিছু থাকত যেটা কোনো কাজ বারবার করত ! সব প্রোগ্রামিং ল্যাঙ্গুয়েজেই লুপ বলে একটি পদ্ধতি আছে যেটি কোনো কাজ বারবার করতে পারে । তুমি লুপে একটি শর্ত বসে দিবে যেটি পূরণ হওয়া পর্যন্ত লুপের ভেতরের কাজ হতেই থাকবে হতেই থাকবে । সি -তে দুটি জনপ্রিয় লুপ হচ্ছে while এবং for ।এখন আমরা while লুপের সাহায্যে সমস্যাটির সমাধান করব :

 #include <stdio.h>
 
 int main()
 {
     int n = 1;
     
     while (n <= 10) {
         printf("%d\n", n);
         n++;
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.১

এখন তুমি দশ এর বদলে যত খুশি বসাতে পারো । যতো বসাবে এক থেকে তত পর্যন্ত প্রিন্ট হবে !

এখন বলোতো, নিচের প্রোগ্রামটির আউটপুট কী হবে :

 #include <stdio.h>
 
 int main()
 {
     int n = 1;
     
     while (n <= 10) {
         n++;
     }
     
     printf("%d\n", n);
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.২

নিচের প্রোগ্রামটি দেখো :

 #include <stdio.h>
 
 int main()
 {
     int n = 1;
     
     while (n <= 10) {
         printf("%d\n", n);
     }
     n++;
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৩

প্রোগ্রামটি রান করালে দেখবে শুধু 1 প্রিন্ট হচ্ছে এবং প্রোগ্রামটি বন্ধ হচ্ছে না । কারণ কী ?

মনে আছে , তোমাকে বলেছিলাম, লুপে দেওয়া শর্ত পূরণ হওয়া পর্যন্ত লুপের ভেতরের কাজ চলতে থাকবে । এখানে আমরা n -এর মান 1 অ্যাসাইন করেছি । আর শর্তে দিয়েছি n <= 10 । এখন n = 1 । স্কিনে 1 প্রিন্ট হবে । আবার শর্ত পরীক্ষা করবে , 1 প্রিন্ট হবে এবং এভাবে চলতেই থাকবে কারণ আমরা লুপের ভেতরে n -এর মান বাড়াচ্ছি না । বুঝতে পেরেছ কি ?

এখন আমরা যদি চাই তো পুরো লুপ না চালিয়েই লুপ থেকে বের হতে পারি ! এর জন্য আমরা break; স্টেটমেন্ট ব্যবহার করব ।

 #include <stdio.h>
 
 int main()
 {
     int n = 1;
     
     while (n <= 100) {
     
         printf("%d\n", n);
         n++;
         
         if (n > 10) {
             break;
         }
         
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৪

প্রোগ্রামটি 1 থেকে 10 প্রিন্ট করবে ।

আবার আমরা যদি চাই লুপের ভেতরের কিছু কাজ করব কিছু করব না তাহলেও পারব । এর জন্য continue; স্টেটমেন্ট ব্যবহার করতে হবে । যার জন্য continue করবে সেই কাজটি এক্সিকিউট ( execute ) হবে না ব্যাস ।

 #include <stdio.h>
 
 int main()
 {
     int n = 0;
     
     while (n < 10) {
         n++;
         
         if (n % 2 == 0) {
             continue;
         }
         
         printf("%d\n", n);
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৫

প্রোগ্রামটি 1 থেকে 10 -এর মধ্যে কেবল বেজোড় সংখ্যাগুলো প্রিন্ট করবে ।

নিচের প্রোগ্রামটি দেখো । প্রোগ্রামটি কি প্রিন্ট করবে বলো তো ?

 #include <stdio.h>
 
 int main()
 {
     int n = 0;
     
     while (n < 10) {
         
         if (n % 2 == 0) {
             continue;
         }
         
         printf("%d\n", n);
         n++;
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৬

প্রোগ্রামটি কিছুই প্রিন্ট করবে না । কারণ কী ? তোমরা নিজেরাই ভেবে বের করো ।

তোমরা কি এখন while লুপ ব্যবহার করে 5 -এর নামতা লিখতে পারবে ? আউটপুট হবে নিচের মত -

5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50

ঘণ্টাখানিক চেষ্টার পরও না পারলে নিচের কোড দেখো । নো চিটিং !

 #include <stdio.h>
 
 int main()
 {
     int n = 5, i = 1;
     
     while (i <= 10) {
         
         printf("%d x %d = %d\n", n, i, 
 n*i);
         i++;
         
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৭


৪.৭ প্রোগ্রামটি for লুপ দিয়ে করলে সেটি হবে এইরকম :

 #include <stdio.h>
 
 int main()
 {
     int i, n = 5;
     
     for (i = 1; i <= 10; i++) {
     
         printf("%d x %d = %d\n", n, i, 
 n*i);
 
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৮

for লুপের প্রথম বন্ধনীর ভেতরের তিনটি অংশ দেখো । প্রতিটি অংশ সেমিকোলন দিয়ে আলাদা । প্রোগ্রামটি যখন লুপের ভেতরে ঢুকবে তখন নিচের তিনটি কাজ হয় :
  1. প্রথম সেমিকোলনের আগে যেই কাজটি করতে বলা হয়েছে সেটি করবে ।
  2. এরপর দ্বিতীয় অংশের কাজ হবে । দ্বিতীয় অংশে সাধারণত শর্ত ব্যবহার করা হয় । শর্ত সত্য হলে লুপের ভেতরের অংশের (দ্বিতীয় বন্ধনীর ভেতরের কাজগুলো) কাজ হবে । মিথ্যা হলে লুপে ঢুকবে না ।
  3. তারপর প্রথম বন্ধনীর তৃতীয় অংশের কাজ হবে । তারপর আবার শর্ত পরীক্ষা করবে । মানে দুই নম্বর কাজটি করবে ।

এভাবে দুই আর তিন নম্বর কাজগুলো চলবে যতক্ষণ না শর্ত (দুই নম্বর) মিথ্যা হয় । এক নম্বর কাজ (প্রথম অংশ) কিন্তু আর হবে না ।
প্রথম অংশের কাজ একবারই হয় ।

৪.৮ প্রোগ্রামটি এভাবেও করা যায় :

 #include <stdio.h>
 
 int main()
 {
     int i = 1, n = 5;
     
     for ( ; i <= 10; i++) {
     
         printf("%d x %d = %d\n", n, i, 
 n*i);
 
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.৯

আবার এভাবেও :

 #include <stdio.h>
 
 int main()
 {
     int i = 1, n = 5;
     
     for ( ; ; ) {
     
         printf("%d x %d = %d\n", n, i, 
 n*i);
         i++;
         
         if (i > 10) {
             break;
         }
 
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.১০

মানে কোনো অংশ ওখানে করতে না চাইলে আমরা সেটি ফাঁকা রেখে দিতে পারি । তবে সেমিকোলন কিন্তু অবশ্যই দিতে হবে ।


তোমরা কি জানো , শুধু যোগ করা জানলেই গুণ, ভাগ, বিয়োগ এসবও করা যায় ? এই যেমন 5 x 6 মানে হলো ছয় বার পাঁচ যোগ করা 5+5+5+5+5+5 । 6 - 5 মানে 6 এর সাথে (-5) যোগ করা 6+(-5) । আর 30/6 -এর অর্থ 30 থেকে কতবার 6 বিয়োগ করা যায় ।
এখন তোমরা কি একটি কাজ করতে পারবে ? ৪.৮ প্রোগামটিতে আমরা যে গুণ করেছি (n*i) সেটি না করে যোগ করে প্রোগ্রামটি করতে পারবে । প্রোগ্রামটি কিন্তু বেশ সহজ । একটু বুদ্ধি খাটালেই পারবে ।

 #include <stdio.h>
 
 int main()
 {
     int i, n = 5;
     int m = 0;
     
     for (i = 1; i <= 10; i++) {
         
         m = m + n;
         
         printf("%d x %d = %d\n", n, i, 
 m);
 
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.১১

কম্পিউটারের যোগ করতে যে সময় লাগে, গুণ করতে তার চেয়ে অনেক বেশি সময় লাগে । তাই কোনো প্রোগ্রাম গুণের বদলে যদি যোগ করে করা যায় তবে যোগ করে করাই ভালো ।

এখন আমরা আরেকটি প্রোগ্রাম লিখব যেটি 1 থেকে 20 পর্যন্ত সবগুলো সংখ্যার নামতা লিখতে পারবে । কাজটি সহজভাবে করার জন্য আমরা আরেকটি লুপের সাহায্যে n -এর মান 1 -থেকে 20 পর্যন্ত বাড়াব । আমরা এটি করব লুপের ভেতর লুপ ব্যবহার করে । একে নেস্টেড লুপ (nested loop) বলে ।

 #include <stdio.h>
 
 int main()
 {
     int i, n;
     
     for (n = 1; n <= 20; n++) {
     
         for (i = 1; i <= 10; i++) {
     
             printf("%d x %d = %d\n", 
 n, i, n*i);
         }
 
     }
     
     return 0;
 }
 
 প্রোগ্রাম : ৪.১২

আমরা চাইলে for লুপের ভেতর for বা while অথবা while লুপের ভেতর for বা while লুপ একাধিক বার ব্যবহার করতে পারি । অবশ্য সেটি কখনোই চার বা পাঁচ বারের বেশি দরকার হওয়ার কথা না ।

নেস্টেড লুপ দিয়ে আমরা এখন আরেকটি প্রোগ্রাম লিখব । 1, 2, 3 -এই তিনটি সংখ্যার সব বিন্যাস (permutation) বের করার প্রোগ্রাম । বিন্যাসগুলো ছোট থেকে বড় ক্রমে দেখাতে হবে অর্থাৎ প্রোগ্রামটির আউটপুট হবে নিচের কয়েকটি লাইন :


 1, 2, 3
 1, 3, 2
 2, 1, 3
 2, 3, 1
 3, 1, 2
 3, 2, 1

অর্থাৎ , 1, 2, 3 কে যথাক্রমে a, b, c ধরলে কোনো লাইনেই a = b , a = c এরকম কিছু হওয়া চলবে না । মানে a, b, c আলাদা হবে ।
বুঝতেই পারছ প্রথম সংখ্যাটির জন্য একটি লুপ, দ্বিতীয় সংখ্যার জন্য প্রথম লুপের ভেতর আরেকটি লুপ এবং তৃতীয় সংখ্যাটির জন্য দ্বিতীয় লুপের ভেতর আরোও একটি লুপ দরকার । মানে মোট তিনটি লুপ ।

 #include <stdio.h>
 
 int main()
 {
     int a, b, c;
     
     for (a = 1; a<=3; a++) {
         for (b = 1; b<=3; b++) {
             for (c = 1; c<=3; c++) {
                 printf("%d, %d, %d\n", 
 a, b, c);
             }
         }
     }
                 
     return 0;
 }
 
 প্রোগ্রাম : ৪.১৩

প্রোগ্রামটি রান করালে আউটপুট হবে :
1, 1, 1
1, 1, 2
1, 1, 3
1, 2, 1
1, 2, 2
1, 2, 3
1, 3, 1
1, 3, 2
1, 3, 3
2, 1, 1
2, 1, 2
2, 1, 3
2, 2, 1
2, 2, 2
2, 2, 3
2, 3, 1
2, 3, 2
2, 3, 3
3, 1, 1
3, 1, 2
3, 1, 3
3, 2, 1
3, 2, 2
3, 2, 3
3, 3, 1
3, 3, 2
3, 3, 3
আউটপুট ঠিক আসে নি । আসলে প্রোগ্রামে আমরা এমন কোনো শর্ত দিই নি যেন প্রতি লাইনে a, b, c -এর মান ভিন্ন হয় ।

 #include <stdio.h>
 
 int main()
 {
     int a, b, c;
     
     for (a = 1; a<=3; a++) {
         for (b=1; b<=3 && b!=a; b++) {
             for (c=1;c<=3 && c!=a && 
 c!=b;c++) {
                 printf("%d, %d, %d\n", 
 a, b, c);
             }
         }
     }
                 
     return 0;
 }
 /* c <= 3 && c != a && c != b -এর মানে 
 c -এর মান 3 -এর ছোট বা সমান হবে এবং c -
 এর মান a -এর মানের সমান হওয়া চলবে না 
 এবং c -এর মান b -এর মানের সমান হলেও
 চলবে না । */
 
 প্রোগ্রাম : ৪.১৪

এর আউটপুট হবে :
3, 2, 1
মাত্র একটি লাইন ! আমরা আমাদের প্রোগ্রামে কী ভুল করলাম বলো তো ।

প্রথমে a -এর মান 1 তাই a <= 3 সত্য । প্রোগ্রামটি প্রথম লুপের ভেতর ঢুকে গেল । তারপর দ্বিতীয় লুপের শুরুতে b -এর মান 1 । b <= 3 সত্য । কিন্তু b != a মিথ্যা । তাই প্রোগ্রামটি আর দ্বিতীয় লুপের ভেতর ঢুকবে না । এরপর a -এর মান 1 বাড়ল (a++) । a <= 3 সত্য (a -এর মান 2) । এখন দ্বিতীয় লুপে ঢুকবে । b -এর মান 1 । এবারে b <= 3 এবং b != a দুটি শর্তই সত্য । প্রোগ্রামটি দ্বিতীয় লুপের ভেতর ঢুকে যাবে । তৃতীয় লুপের শুরুতে c -এর মান 1 । c <= 3 সত্য , c != a সত্য কিন্তু c != b মিথ্যা (দুটোর মানই 1) । তাই প্রোগ্রামটি তৃতীয় লুপ থেকে বের হয়ে । কেবল তিনটি শর্তই সত্য হলেই প্রোগ্রামটি তৃতীয় লুপের ভেতর ঢুকবে এবং a, b, c -এর মান প্রিন্ট করবে । এভাবে কিছুক্ষণ গবেষণা করলে তোমরা দেখবে যে যখন a -এর মান 3 , b -এর মান 2 , c -এর মান 1 তখনই কেবল সব শর্ত সত্য হয় আর আমরা আউটপুট পাই : 3, 2, 1 ।

আসলে দ্বিতীয় লুপে আমরা b -এর মান a -এর মানের সমান হলে লুপ থেকে বের হয়ে যাচ্ছি । এই কাজটি করা ঠিক হচ্ছে না । আমাদের উচিৎ দুটো মান সমান হলে পরবর্তী মানের জন্য চেষ্টা করা । আর মান দুটো সমান না হলেই কেবল পরবর্তী করা ।

 #include <stdio.h>
 
 int main()
 {
     int a, b, c;
     
     for (a = 1; a<=3; a++) {
         for (b = 1; b<=3; b++) {
             if (b != a) {
                 for (c=1; c<=3; c++) {
                     if(c!=b && c!=a) {
                         printf("%d, %d
 , %d\n", a, b, c);    
                     }
                 }
             }
         }
     }
                 
     return 0;
 }
 
 প্রোগ্রাম : ৪.১৫


প্রোগ্রামটি চালালে আমরা নিচের আউটপুট পাব যা আমরা চাচ্ছিলাম -

    1, 2, 3 
    1, 3, 2 
    2, 1, 3 
    2, 3, 1 
    3, 1, 2 
    3, 2, 1 
    
 
সমাধানটা আরো সহজেই করা যেত -

 #include <stdio.h>
 
 int main()
 {
     int a, b, c;
     for (a=1;a<=3;a++) {
         for (b=1;b<=3;b++) {
             for (c=1;c<=3;c++) {
                 if (b!=a && c!=a && 
c!=b) { printf("%d, %d,
%d\n", a, b, c); } } } } return 0; } প্রোগ্রাম : ৪.১৬

এখানে আমাদের বেশি চিন্তা করতে হলো না । কেবল প্রিন্ট করার সময় a, b, c তিনটির মান পরস্পরের সমান নয়, সেটি নিশ্চিত করে নিলেই হলো ।

এখন তোমরা পারফেক্ট নাম্বার খুঁজে বের করার জন্য একটি প্রোগ্রাম লিখে ফেলো । যে সংখ্যার সবগুলো উৎপাদককে ( 1 সহ , কিন্তু মূল সংখ্যাটি ছাড়া ) যোগ করলে সেই সংখ্যাটিই পাওয়া যায় সেটাই পারফেক্ট সংখ্যা । যেমন : 6 ( 1 + 2 + 3 = 6 ) । প্রথম কোটির ভেতরে পারফেক্ট নাম্বার আছে মোটে চারটি । এখন পর্যন্ত কোনো বিজোড় পারফেক্ট নাম্বার খুঁজে পাওয়া যায় নি । পারফেক্ট নাম্বারের তালিকা : en.m.wikipedia.org/wiki/List_of_perfect_numbers । পারফেক্ট নাম্বার নিয়ে একটি মজার ব্যাপার আছে । সেটি পরে বলব । আপাতত ঝটপট প্রোগ্রামটি করে ফেলো । oK?

No comments:

Post a Comment