Skip to content

মডিউল ৬ঃ লুপ প্রবলেম সলভিং এবং নেস্টেড লুপ

মডিউল ৬-০: সূচনা

এই মডিউলে আমরা কি কি শিখবোঃ

  • লুপ রিভিশন দিব।
  • কোডফরসেস থেকে নিচের প্রবলেম গুলো সল্ভ করব।

মডিউল ৬-১, ৬-২: ইনক্রিমেন্ট ডিক্রিমেন্ট অপারেটর

i = i+1 এটাকে সংক্ষেপে i++ অথবা ++i লিখা যায়।

i = i-1 এটাকে সংক্ষেপে i-- অথবা --i লিখা যায়।

i++ এবং ++i ২টি আসলে একই যদি i এর মান বাড়ানোর ব্যাপার থাকে।

i = 10 রেখে তারপর যদি আমরা i++ করি এবং তারপর যদি i এর মান প্রিন্ট করি তাহলে 11 পাব।

আবার i = 10 রেখে তারপর যদি আমরা ++i করি এবং তারপর যদি i এর মান প্রিন্ট করি তাহলেও আমরা 11 পাব।

কিন্তু এই ২টির মধ্যে মেজর পার্থক্য আছে।

i++ কে বলা হয় post increment, ++i কে বলা হয় pre increment

(i++) post increment:

এখানে ইঙ্ক্রিমেন্ট পরে হয় আগে কাজ হয়। যেমন আমরা যদি লিখিঃ

c
i = 10;
x = i++;

তাহলে এখানে আগে i এর মান (10) x এর মধ্যে এসাইন হবে তারপর i এর মান 1 বেড়ে 11 হয়ে যাবে। এটার পর আমরা যদি x কে প্রিন্ট করি তাহলে 10 প্রিন্ট হবে।

Code:

c
#include <stdio.h>

int main()
{
    int i=10;
    int x=i++;
    printf("x:%d i:%d",x,i);
    return 0;
}

রান করলে আমরা দেখতে পাব x এর মান 10 i এর মান 11

(++i) pre increment:

এখানে ইঙ্ক্রিমেন্ট আগে হয় পরে কাজ হয়। যেমন আমরা যদি লিখিঃ

c
i = 10;
x = ++i;

তাহলে এখানে আগে i এর মান 1 বেড়ে 11 হবে এবং তারপর i এর মান (11) x এর মধ্যে এসাইন হবে। এটার পর আমরা যদি x কে প্রিন্ট করি তাহলে 11 প্রিন্ট হবে।

Code:

c
#include <stdio.h>

int main()
{
    int i=10;
    int x=++i;
    printf("x:%d i:%d",x,i);
    return 0;
}

রান করলে আমরা দেখতে পাব x এর মান 11 i এর মান 11


মডিউল ৬-৩: ইভেন নাম্বারস

Problem Statement:

ইনপুটে একটি সংখ্যা দেওয়া থাকবে। আমাদের ১ থেকে ঐ সংখ্যা পর্যন্ত সবগুলো জোড় সংখ্যা প্রিন্ট করতে হবে। আর যদি কোন জোড় না থাকে তাহলে -১ প্রিন্ট করতে হবে।

Solution:

যেহেতু জোড় সংখ্যা ২ থেকে শুরু হয় তারমানে ইনপুটে শুধুমাত্র ১ থাকলেই আমাদের -১ প্রিন্ট করতে হবে। বাকি সবক্ষেত্রে আমরা কোন না কোন জোড় সংখ্যা প্রিন্ট করতে পারব। শুরুতে আমরা কন্ডিশন দিয়ে চেক করতে পারি ইনপুটের মান ১ কিনা। যদি ১ হয় তাহলে -১ প্রিন্ট করে দিব। আর নাহলে লুপ চালিয়ে জোড় সংখ্যা প্রিন্ট করব।

Code:

c
#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);    // ইনপুট নিচ্ছি
    if(n==1)            // চেক করছি ইনপুটের মান ১ কিনা
    {
        printf("-1\n"); // ১ হলে -১ প্রিন্ট করছি
    }
    else                // ১ নাহলে
    {
        for(int i=1; i<=n; i=i+1) // ১ থেকে n পর্যন্ত লুপ চালাচ্ছি
        {
            if(i%2==0)  // চেক করছি জোড় কিনা
            {
                printf("%d\n", i); // জোড় হলে প্রিন্ট করছি
            }
        }
    }
    return 0;
}

মডিউল ৬-৪, ৬-৫: ইভেন, ওড, পজিটিভ, নেগেটিভ

Problem Statement:

ইনপুটে একটি সংখ্যা দেওয়া থাকবে। তারপর ততগুলো সংখ্যা দেওয়া থাকবে। আমাদের সবগুলো সংখ্যা থেকে কাউন্ট করতে হবে কয়টা পজিটিভ, কয়টা নেগেটিভ, কয়টা ওড, কয়টা ইভেন।

Solution:

প্রথমে সংখ্যাটি ইনপুট নিব। তারপর ততবার লুপ চালিয়ে প্রতিবার একটা করে সংখ্যা ইনপুট নিব। জোড়, বিজোড়, পজিটিভ, নেগেটিভ কাউন্ট করার জন্য ৪ টি কাউন্ট ভেরিয়েবল নিয়ে নিব। প্রতিটি সংখ্যা ইনপুট নেওয়ার পর চেক করে দেখব সেটি জোড় কিনা, জোড় হলে জোড়ের কাউন্ট ১ বাড়িয়ে দিব আর নাহলে বিজোড়ের কাউন্ট ১ বাড়িয়ে দিব। তারপর চেক করব পজিটিভ কিনা, পজিটিভ হলে পজিটিভের কাউন্ট ১ বাড়িয়ে দিব। নেগেটিভ হলে নেগেটিভের কাউন্ট ১ বাড়িয়ে দিব।

Code:

c
#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);    // ইনপুট নিচ্ছি
    int a;
    int even=0,odd=0,pos=0,neg=0;    // কাউন্ট করার জন্য ৪টা ভেরিয়েবল নিচ্ছি। শুরুতে সবগুলো ০
    for(int i=1; i<=n; i=i+1)    // লুপ চালাচ্ছি
    {
        scanf("%d", &a);     // প্রতিবার একটা করে সংখ্যা ইনপুট নিচ্ছি
        if(a%2==0)          // চেক করে দেখছি সংখ্যাটি জোড় কিনা
        {
            even++;          // জোড় হলে জোড়ের কাউন্ট এর মান ১ বাড়িয়ে দিচ্ছি
        }
        else
        {
            odd++;           // জোড় না হলে বিজোড়ের কাউন্ট এর মান ১ বাড়িয়ে দিচ্ছি
        }


        if(a>0)              // চেক করে দেখছি সংখ্যাটি পজিটিভ অর্থাৎ ০ এর থেকে বড় কিনা
        {
            pos++;           // পজিটিভ হলে পজিটিভের কাউন্ট এর মান ১ বাড়িয়ে দিচ্ছি
        }
        else if(a<0)         // চেক করে দেখছি সংখ্যাটি নেগেটিভ অর্থাৎ ০ এর থেকে ছোট কিনা
        {
            neg++;           // নেগেটিভ হলে নেগেটিভের কাউন্ট এর মান ১ বাড়িয়ে দিচ্ছি
        }

    }
    printf("Even: %d\nOdd: %d\nPositive: %d\nNegative: %d\n",even,odd,pos,neg);
    return 0;
}

মডিউল ৬-৬: ফিক্সড পাসওয়ার্ড

Problem Statement:

ইনপুটে কতগুলো পাসওয়ার্ড দেওয়া থাকবে। আপনাকে বলতে হবে পাসওয়ার্ডটি কারেক্ট কিনা। কারেক্ট হলে "Correct" প্রিন্ট করতে হবে আর ভুল হলে "Wrong" প্রিন্ট করতে হবে। "Correct" প্রিন্ট করার পর আর কিছু প্রিন্ট করা যাবে না। প্রোগ্রামটি থামিয়ে দিতে হবে।

Solution:

যেহেতু এখানে শুরুতে বলে দেওয়া হচ্ছে না কতগুলো ইনপুট থাকবে তাই এখানে আমাদের EOF ব্যাবহার করতে হবে। EOF এর ফুল ফর্ম হচ্ছে End Of File। EOF যতক্ষন ইনপুট ফাইল শেষ না হচ্ছে ততক্ষন ইনপুট নেয়। যেহেতু আমরা জানি না কতগুলো ইনপুট থাকবে এবং কতবার লুপ চালাতে হবে তাই আমরা এখানে While লুপ ব্যাবহার করতে পারি। লুপের মধ্যে চেক করে দেখতে পারি পাসওয়ার্ডটি কারেক্ট কিনা। কারেক্ট হলে প্রিন্ট করে ব্রেক করে দিতে পারি।

Code:

c
#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)    // যতক্ষন না ইনপুটের ফাইল শেষ হচ্ছে ততক্ষন লুপ চলবে এবং ইনপুট নিবে
    {
        if(n==1999)            // যদি পাসওয়ার্ডটি কারেক্ট হয়
        {
            printf("Correct\n"); // তাহলে কারেক্ট প্রিন্ট করা হচ্ছে
            break;              // এবং লুপ থামিয়ে প্রোগ্রাম টারমিনেট করে দেওয়া হচ্ছে
        }
        else // কারেক্ট না হলে
        {
            printf("Wrong\n"); // wrong প্রিন্ট করা হচ্ছে
        }
    }
    return 0;
}

মডিউল ৬-৭, ৬-৮: Max, Min

Problem Statement:

ইনপুটে একটি সংখ্যা দেওয়া থাকবে। তারপর ততগুলো সংখ্যা দেওয়া থাকবে। সবগুলো সংখ্যা থেকে সবথেকে বড় সংখ্যাটি প্রিন্ট করতে হবে।

Solution:

সবথেকে বড় ভেরিয়েবল ট্র্যাক রাখার জন্য একটি ম্যাক্স ভেরিয়েবল নিয়ে তাতে শুরুতে সবথেকে ছোট নাম্বার রেখে দিতে পারি (INT_MIN)। তারপর লুপ চালিয়ে প্রতিটি ভেলু ইনপুট নিয়ে চেক করে দেখতে পারি সেটি ম্যাক্স ভেরিয়েবল থেকে বড় কিনা। যদি বড় হয় তাহলে এটিই এখন আমাদের সবথেকে বড় সংখ্যা। এটিকে ম্যাক্স ভেরিয়েবলে রেখে দিতে পারি।

Code:

c
#include <stdio.h>
#include <limits.h>    // INT_MIN, INT_MAX এর জন্য এই হেডার ফাইলটি ইনক্লুড করা হচ্ছে
int main()
{
    int n;
    scanf("%d", &n);    // কতগুলো সংখ্যা থাকবে তা ইনপুট নিচ্ছি
    int a,max=INT_MIN;    // শুরুতে সবথেকে ছোট নাম্বার রেখে দিচ্ছি
    for(int i=1; i<=n; i++)
    {
        scanf("%d", &a);     // লুপ চালিয়ে প্রতিবার সংখ্যা ইনপুট নিচ্ছি
        if(a>max)          // চেক করে দেখছি যে সংখ্যাটি ম্যাক্স এর থেকে বড় কিনা
        {
            max=a;          // বড় হলে ম্যাক্স ভেরিয়েবলকে আপডেট করছি
        }
    }
    printf("%d",max);
    return 0;
}

সেইমভাবে আমরা চাইলে মিনিমাম নাম্বারটিও বের করে ফেলতে পারি। শুরুতে সবথেকে বড় সংখ্যা (INT_MAX) রাখতে হবে।

c
#include <stdio.h>
#include <limits.h>
int main()
{
    int n;
    scanf("%d", &n);
    int a,max=INT_MIN,min=INT_MAX;
    for(int i=1; i<=n; i++)
    {
        scanf("%d", &a);
        if(a>max)
        {
            max=a;
        }
        if(a<min)      // চেক করা হচ্ছে যে সংখ্যাটি মিনিমাম এর থেকেও ছোট কিনা
        {
            min=a;      // ছোট হলে সেইমভাবে মিনিমাম ভেরিয়েবলটি আপডেট করা হচ্ছে
        }
    }
    printf("%d %d\n",min,max);
    return 0;
}

মডিউল ৬-৯: মাল্টিপ্লিকেশন টেবিল

Problem Statement:

ইনপুটে একটি সংখ্যা দেওয়া থাকবে। ঐ সংখ্যার নামতা প্রিন্ট করতে হবে ১২ পর্যন্ত।

Solution:

আমরা সিম্পলি ১ থেকে ১২ পর্যন্ত লুপ চালিয়ে নামতা প্রিন্ট করে দিতে পারি।

Code:

c
#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);    // সংখ্যাটি ইনপুট নেওয়া হচ্ছে।
    for(int i=1; i<=12; i++)    // ১ থেকে ১২ পর্যন্ত লুপ চালানো হচ্ছে।
    {
        printf("%d * %d = %d\n", n, i, n*i); // প্রথমে সংখ্যাটি প্রিন্ট হচ্ছে, তারপর পর্যায়ক্রমে ১ থেকে ১২ এবং শেষে এদের গুনফল
    }
    return 0;
}

মডিউল ৬-১০: ডিজিটস

Problem Statement:

ইনপুটে প্রথমে টেস্টকেস নাম্বার থাকবে। প্রতিটি টেস্টকেসে একটি সংখ্যা দেওয়া থাকবে। আমাদের সংখ্যাটির প্রতিটি ডিজিট ডান থেকে বামে আলাদা করে স্পেস দিয়ে প্রিন্ট করতে হবে।

Solution:

টেস্টকেস ইনপুট নিয়ে টেস্টকেসের জন্য লুপ চালিয়ে দিতে পারি। প্রতিটি টেস্টকেসে সংখ্যা ইনপুট নেওয়ার পর আমরা যদি সংখ্যাটিকে ১০ দিয়ে ভাগ করে ভাগশেষ গুলো নিতে থাকি তাহলেই ঐ সংখ্যার ডিজিটস গুলো পেয়ে যাব। একটি ভাগশেষ অর্থাৎ একটি ডিজিট পেয়ে গেলে তারপর আমরা ঐ ডিজিটটি বাদ দিয়ে দেওয়ার জন্য ১০ দিয়ে ভাগ করা দিতে পারি।

একটি সংখ্যার লাস্ট ডিজিটটি পেতে হলে সেটিকে ১০ দিয়ে ভাগ করে ভাগশেষটি নিয়ে নেওয়া যায়।

যেমনঃ ১২৩ % ১০ = ৩ (লাস্ট ডিজিট)

একটি সংখ্যা থেকে লাস্ট ডিজিটটি বাদ দিতে হলে সেটিকে ১০ দিয়ে ভাগ করে দেওয়া যায়。

যেমনঃ ১২৩ / ১০ = ১২ (লাস্ট ডিজিট বাদ গেল)

Code:

c
#include <stdio.h>

int main()
{
    int test;
    scanf("%d", &test);    // টেস্টকেস ইনপুট নেওয়া হচ্ছে
    for(int t=1; t<=test; t++)    // টেস্টকেসের জন্য লুপ চালানো হচ্ছে
    {
        int n;
        scanf("%d", &n);    // সংখ্যা ইনপুট নেওয়া হচ্ছে
        do
        {
            printf("%d ", n%10);    // ১০ দিয়ে ভাগ করে ভাগশেষ গুলো প্রিন্ট করা হচ্ছে
            n=n/10;    // একটি ভাগশেষ অর্থাৎ একটি ডিজিট প্রিন্ট হয়ে গেলে ঐ ডিজিটটি বাদ দিয়ে দেওয়ার জন্য ১০ দিয়ে ভাগ করা হচ্ছে।
        }
        while(n!=0);    // এভাবে ভাগ করতে করতে সংখ্যাটি ০ হয়ে গেলে লুপ থামিয়ে দেওয়া হবে।
        printf("\n");
    }
    return 0;
}

মডিউল ৬-১১, ৬-১২: নেস্টেড ফর লুপ

আমরা নেস্টেড কন্ডিশন দেখেছিলাম। সেইমভাবে আমাদের নেস্টেড লুপের ও প্রয়োজন হতে পারে। আমরা একই কাজ বারবার করতে চাইলে লুপ ব্যাবহার করি। সেই বারবার করা কাজটাই যদি আমাদের আরো করানো লাগে তখন আমরা সেটিকে আরেকটা লুপের মধ্যে রেখে দিতে পারি। তখন সেটি হয়ে যাবে নেস্টেড লুপ।

যেমন আমরা যদি চাই ১ থেকে ১০ পর্যন্ত প্রিন্ট করতে ৫ বার। তখন আমরা ১ থেকে ১০ পর্যন্ত প্রিন্ট করার জন্য একটি লুপ লিখতে পারি এবং ৫ বার এই কাজটি করার জন্য এই পুরো লুপটিকে আরেকটি লুপের মধ্যে রেখে দিতে পারি।

Code:

c
#include <stdio.h>

int main()
{
    for(int i=1; i<=5; i++)    // ৫ বার ভিতরের লুপটি চালানোর জন্য লুপ
    {
        for(int j=1; j<=10; j++)    // ১ থেকে ১০ প্রিন্ট করার লুপ
        {
            printf("%d ", j);
        }
        printf("\n");
    }
    return 0;
}

Released under the MIT License.