Control Flow II — Loops & Invariants

while, do-while, for — ও শুদ্ধতার গণিত

~30 min Intermediate 15 practice problems Live code

1. Why Loops?

A loop lets a fixed piece of code handle a variable-sized problem. It is also mathematical induction in executable form — which is why loop invariants matter so much.

Loop-এর মাধ্যমে একই কোড-ব্লক বারবার চালানো যায় — ইনপুট যত বড়ই হোক। এটি আসলে গাণিতিক induction-এর executable রূপ। সেজন্যই loop invariant এত গুরুত্বপূর্ণ।

2. Three Loop Forms — All Live

while — test first
while.c — stdin: 5
#include <stdio.h>

int main(void) {
    int n, i = 0;
    scanf("%d", &n);
    while (i < n) {
        printf("%d ", i);
        i++;
    }
    putchar('\n');
    return 0;
}
do-while — run at least once
do_while.c — stdin: -3 / -1 / 7
#include <stdio.h>

int main(void) {
    int n;
    do {
        scanf("%d", &n);
        if (n <= 0) puts("Please enter a positive number…");
    } while (n <= 0);
    printf("Accepted: %d\n", n);
    return 0;
}

do-while body সবসময় অন্তত একবার চলে — menu এবং input validation-এ উপযোগী।

for — the workhorse
for.c
#include <stdio.h>

int main(void) {
    long sum = 0;
    for (int i = 1; i <= 100; i++) sum += i;
    printf("1 + 2 + ... + 100 = %ld\n", sum);
    return 0;
}

for(init; test; update) আসলে একটি while loop-এরই compact form। তিনটি অংশই optional — for(;;) মানে infinite loop।

3. break, continue, goto

break_cont.c
#include <stdio.h>

int main(void) {
    int arr[] = {3, -1, 5, 2, -7, 42, 9};
    int target = 42;

    for (int i = 0; i < 7; i++) {
        if (arr[i] < 0) continue;    // skip negatives
        if (arr[i] == target) {
            printf("Found at index %d\n", i);
            break;                       // exit the loop
        }
    }
    return 0;
}
break পুরো loop থেকে বের করে দেয়, continue শুধু বর্তমান iteration বাদ দিয়ে পরেরটায় চলে যায়। goto সাধারণত পরিহার্য, কিন্তু cleanup-এ একটিমাত্র label-এর জন্য ব্যবহার করা যায় — এই কৌশল Linux kernel-এ প্রচলিত।

4. Loop Invariants — Proving Correctness

Every loop body should maintain a condition that is true before, during, and after the loop. That is a loop invariant. Stating it forces clarity and catches bugs before you run.

Example — Sum of 1..N Invariant: at the top of each iteration, s == 1+2+...+i-1. After the body (s += i; i++;) the invariant still holds. When the loop exits with i == n+1, s equals n(n+1)/2.
sum_invariant.c
#include <stdio.h>

int main(void) {
    int n = 10;
    long s = 0;
    for (int i = 1; i <= n; i++) {
        s += i;
        // Invariant: s == 1+2+...+i
    }
    printf("loop sum     = %ld\n", s);
    printf("formula sum  = %d\n", n * (n+1) / 2);
    return 0;
}
Termination proof প্রতিটি loop-এর একটি progress measure থাকা উচিত — একটি হ্রাসমান, non-negative integer। এটির অস্তিত্ব প্রমাণ করে যে loop অসীম নয়। উদাহরণ: এখানে n - i প্রতিটি iteration-এ এক করে কমে — শূন্যে পৌঁছালে loop থামে।

5. Nested Loops — Time-Complexity Warning

for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
        mat[i][j] = i * j;    // O(n²)

প্রতিটি nested level runtime-কে multiply করে। n বড় হলে সাবধান — n = 10⁵ হলে n² = 10¹⁰, এটি কয়েক মিনিটও চলতে পারে।

6. Practice Problems

  1. Print numbers 1 to N using all three loop forms.
    ১ থেকে N পর্যন্ত তিন ধরনের loop দিয়ে প্রিন্ট করুন।
    ✨ Show Answer
    three_loops.c — stdin: 5
    #include <stdio.h>
    int main(void) {
        int n; scanf("%d", &n);
    
        printf("while : ");
        int i = 1; while (i <= n) { printf("%d ", i); i++; } putchar('\n');
    
        printf("do-wh : ");
        i = 1; if (n > 0) do { printf("%d ", i); i++; } while (i <= n); putchar('\n');
    
        printf("for   : ");
        for (int k = 1; k <= n; k++) printf("%d ", k);
        putchar('\n');
        return 0;
    }
  2. Compute factorial of N with a loop.
    N-এর factorial loop দিয়ে বের করুন।
    ✨ Show Answer
    fact.c — stdin: 10
    #include <stdio.h>
    int main(void) {
        int n; scanf("%d", &n);
        long long f = 1;
        for (int i = 2; i <= n; i++) f *= i;
        printf("%d! = %lld\n", n, f);
        return 0;
    }
  3. Print all primes up to N (trial division).
    ১ থেকে N পর্যন্ত সব prime প্রিন্ট করুন।
    ✨ Show Answer
    primes.c — stdin: 50
    #include <stdio.h>
    int is_prime(int n) {
        if (n < 2) return 0;
        for (int i = 2; i*i <= n; i++) if (n % i == 0) return 0;
        return 1;
    }
    int main(void) {
        int n; scanf("%d", &n);
        for (int i = 2; i <= n; i++) if (is_prime(i)) printf("%d ", i);
        putchar('\n');
        return 0;
    }
  4. Print multiplication tables for 1..10.
    ১ থেকে ১০-এর গুণের সারণি প্রিন্ট করুন।
    ✨ Show Answer
    mult.c
    #include <stdio.h>
    int main(void) {
        for (int i = 1; i <= 10; i++) {
            for (int j = 1; j <= 10; j++) printf("%4d", i*j);
            putchar('\n');
        }
        return 0;
    }
  5. Reverse an integer (123 → 321) without arrays.
    Array ছাড়াই একটি integer উল্টান (123 → 321)।
    ✨ Show Answer
    reverse_int.c — stdin: 12345
    #include <stdio.h>
    int main(void) {
        int n, r = 0;
        scanf("%d", &n);
        while (n) { r = r * 10 + n % 10; n /= 10; }
        printf("%d\n", r);
        return 0;
    }
  6. Check whether a number is a palindrome.
    একটি সংখ্যা palindrome কি না যাচাই করুন।
    ✨ Show Answer
    pal.c — stdin: 12321
    #include <stdio.h>
    int main(void) {
        int n, orig, r = 0;
        scanf("%d", &n); orig = n;
        while (n) { r = r * 10 + n % 10; n /= 10; }
        printf("%s\n", orig == r ? "palindrome" : "not palindrome");
        return 0;
    }
  7. Sum of digits of a number.
    একটি সংখ্যার digit-এর যোগফল বের করুন।
    ✨ Show Answer
    digit_sum.c — stdin: 4829
    #include <stdio.h>
    int main(void) {
        int n, s = 0;
        scanf("%d", &n);
        while (n) { s += n % 10; n /= 10; }
        printf("digit sum = %d\n", s);
        return 0;
    }
  8. Count the digits of a positive integer.
    একটি পূর্ণসংখ্যার digit সংখ্যা গুনে বের করুন।
    ✨ Show Answer
    digit_count.c
    #include <stdio.h>
    int main(void) {
        int n, c = 0;
        scanf("%d", &n);
        if (n == 0) c = 1;
        while (n) { c++; n /= 10; }
        printf("digits = %d\n", c);
        return 0;
    }
  9. Print the first N Fibonacci numbers iteratively.
    প্রথম N Fibonacci সংখ্যা iteratively প্রিন্ট করুন।
    ✨ Show Answer
    fib.c — stdin: 10
    #include <stdio.h>
    int main(void) {
        int n; scanf("%d", &n);
        long a = 0, b = 1;
        for (int i = 0; i < n; i++) {
            printf("%ld ", a);
            long t = a + b; a = b; b = t;
        }
        putchar('\n');
        return 0;
    }
  10. Print a diamond of * of height 2N−1.
    উচ্চতা 2N−1 বিশিষ্ট *-এর diamond pattern প্রিন্ট করুন।
    ✨ Show Answer
    diamond.c — stdin: 4
    #include <stdio.h>
    int main(void) {
        int n; scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            for (int s = 0; s < n - i; s++) putchar(' ');
            for (int k = 0; k < 2*i - 1; k++) putchar('*');
            putchar('\n');
        }
        for (int i = n - 1; i >= 1; i--) {
            for (int s = 0; s < n - i; s++) putchar(' ');
            for (int k = 0; k < 2*i - 1; k++) putchar('*');
            putchar('\n');
        }
        return 0;
    }
  11. GCD of two numbers using the Euclidean algorithm with a loop.
    Euclidean algorithm দিয়ে loop ব্যবহার করে GCD বের করুন।
    ✨ Show Answer
    gcd.c — stdin: 48 36
    #include <stdio.h>
    int main(void) {
        int a, b; scanf("%d %d", &a, &b);
        while (b) { int t = b; b = a % b; a = t; }
        printf("gcd = %d\n", a);
        return 0;
    }
  12. Print the first N rows of Pascal's triangle.
    Pascal's triangle-এর প্রথম N সারি প্রিন্ট করুন।
    ✨ Show Answer
    pascal.c — stdin: 6
    #include <stdio.h>
    int main(void) {
        int n; scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            long v = 1;
            for (int j = 0; j <= i; j++) {
                printf("%5ld", v);
                v = v * (i - j) / (j + 1);
            }
            putchar('\n');
        }
        return 0;
    }
  13. For each loop above, write its loop invariant in one line.
    উপরের প্রতিটি loop-এর invariant এক লাইনে লিখুন।
    ✨ Show Answer
    • Sum: top of iteration i → s == 1+…+(i-1)।
    • Factorial: top of iteration i → f == (i-1)!।
    • Reverse-int: each step → r = reverse of the digits consumed so far।
    • GCD: always → gcd(a, b) = gcd of the original inputs।
    • Fibonacci: at iteration i → a == F(i), b == F(i+1)।
  14. Prove that the Euclidean GCD loop terminates.
    প্রমাণ করুন Euclidean GCD loop অবশ্যই থামে।
    ✨ Show Answer

    প্রতিটি iteration-এ b-এর মান a % b হয়, যা পুরোনো b-এর চেয়ে কঠোরভাবে ছোট এবং অ-নেতিবাচক। যেহেতু non-negative integer-এর সীমিত সংখ্যক মান আছে, b শেষমেশ 0-তে পৌঁছাবে — তখনই loop থামে।

  15. When is for(;;) with break cleaner than while(cond)?
    while(cond)-এর তুলনায় for(;;) + break কখন বেশি পরিষ্কার?
    ✨ Show Answer

    যখন loop-এর মাঝখানে কোনো শর্তে exit করতে হয় (পড়া, যাচাই করা, তারপর break), অথবা একাধিক exit path থাকে — তখন for(;;)-এ code পড়া সহজ হয়, কারণ সব exit condition body-র ভেতর স্পষ্ট থাকে। Menu loop ও parser state-machine সাধারণত এই pattern ব্যবহার করে।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
LoopA construct that repeats a block of code.একটি code block বারবার চালানোর কাঠামো।
IterationOne full pass through the loop body.Loop body-র এক চক্র সম্পূর্ণ চালানো।
whileTests condition first, then runs the body.আগে শর্ত যাচাই, পরে body চালানো।
forCompact loop with init, condition, update.init/condition/update যুক্ত সংক্ষিপ্ত loop।
do-whileRuns the body once, then tests condition.Body একবার চালিয়ে তারপর শর্ত যাচাই।
CounterThe variable controlling loop iteration count.Loop-এর iteration গণনা করা variable।
breakExits the innermost loop.সবচেয়ে ভিতরের loop থেকে বের হওয়া।
continueSkips to the next iteration.পরবর্তী iteration-এ চলে যাওয়া।
Loop InvariantA condition true before and after every iteration.প্রতি iteration-এর আগে ও পরে সত্য — এমন শর্ত।
TerminationProof that the loop will eventually stop.Loop যে শেষ হবে তার প্রমাণ।
Infinite LoopA loop whose condition never becomes false.যে loop-এর শর্ত কখনো false হয় না।
Off-by-one ErrorLooping one too many or one too few times.একবার বেশি বা একবার কম iterate করার ভুল।
Nested LoopA loop inside another loop.একটি loop-এর ভিতরে আরেকটি loop।

Summary — Module 10

Three loop forms, one idea — iterate with a termination condition. Always be able to write the invariant and prove termination. break/continue are fine; goto is fine in cleanup blocks. Watch out for nested loops on large n.

Next Module → Functions — ঘোষণা, scope ও storage class।