Computational Thinking & Mathematical Reasoning

প্রোগ্রামারের মতো চিন্তা করা শিখুন

Read: ~35 min Beginner 8 practice problems Live code runner

1. The Mistake Most Beginners Make

Most beginners open the code editor and start typing. Then they get stuck. Then they Google. Then they copy-paste. Then the program almost works. Then they give up.

Professional programmers do the opposite: they think first, code last. Before writing a single line, they break down the problem, pick a strategy, check that the strategy is correct, and only then begin typing.

বেশিরভাগ শিক্ষার্থী কোড এডিটর খুলেই সরাসরি টাইপ করতে শুরু করেন। একটু পরেই সমস্যায় পড়েন, Google-এ খোঁজেন, কোথাও থেকে copy-paste করেন, এবং শেষে হতাশ হয়ে পড়েন। অভিজ্ঞ প্রোগ্রামাররা ঠিক উল্টোটা করেন — আগে চিন্তা, তারপর কোড। একটি লাইন লেখার আগেই তাঁরা সমস্যাটিকে ছোট ছোট অংশে ভাগ করেন, একটি কৌশল বেছে নেন, যাচাই করেন এটি সঠিক কি না, এবং তারপর কোড লেখা শুরু করেন।
Rule of this course Do not write code until you can explain your algorithm to a friend in simple words.
কোর্সের নিয়ম: কোনো বন্ধুকে সহজ ভাষায় নিজের algorithm বোঝাতে না পারলে কোড লেখা শুরু করবেন না।

2. The Four Pillars of Computational Thinking

Computer scientist Jeannette Wing summed up programmer-thinking in four mental moves. Every time you solve a problem, you use them — consciously or not.

কম্পিউটার বিজ্ঞানী Jeannette Wing প্রোগ্রামার-চিন্তাধারাকে চারটি ধাপে সাজিয়েছেন। আপনি যখনই কোনো সমস্যা সমাধান করেন, সচেতনভাবে বা অজান্তে — এই চারটি ধাপ অনুসরণ করেন।
1. Decomposition
বড় একটি সমস্যাকে ছোট, সমাধানযোগ্য অংশে ভাগ করা।
2. Pattern Recognition
আগের সমস্যার সাথে মিল খুঁজে বের করা।
3. Abstraction
অপ্রয়োজনীয় বিস্তারিত বাদ দিয়ে শুধু গুরুত্বপূর্ণটি রাখা।
4. Algorithmic Thinking
ধাপে ধাপে একটি পরিষ্কার সমাধান লেখা।
1 · Decomposition বড় সমস্যা ছোট করে ভাগ করা 2 · Pattern পুরাতন প্যাটার্ন চিনে নেওয়া 3 · Abstraction অপ্রয়োজনীয় বিস্তারিত বাদ 4 · Algorithmic ধাপে ধাপে সমাধান লেখা Figure 2.1 — Computational thinking-এর চারটি স্তম্ভ।

3. What Is an Algorithm, Really?

An algorithm is a finite sequence of unambiguous instructions that, given valid input, produces the correct output in finite time. It has five required properties:

একটি algorithm হলো এমন একটি নির্দিষ্ট সংখ্যক, পরিষ্কার নির্দেশের ধারা যা — সঠিক input পেলে — নির্দিষ্ট সময়ের মধ্যে সঠিক output তৈরি করে। এর পাঁচটি বৈশিষ্ট্য থাকা বাধ্যতামূলক।
  • Finiteness — must end after finitely many steps. (নির্দিষ্ট ধাপে শেষ হতে হবে)
  • Definiteness — every step is precise and unambiguous. (প্রতিটি ধাপ স্পষ্ট)
  • Input — takes zero or more valid inputs.
  • Output — produces one or more outputs.
  • Effectiveness — each step is doable by a machine in finite time.
Everyday Example — Making Tea
ALGORITHM make_tea:
  1. Boil water in a pot.
  2. Add tea leaves and sugar.
  3. Wait 3 minutes.
  4. Add milk.
  5. Strain into a cup.
  6. Serve.

This looks informal, but it is a real algorithm. Every property above holds.

4. Pseudocode — The Language of Thinking

Pseudocode is half-English, half-programming. You can express the logic without worrying about semicolons or braces. Then translate it into real code.

Pseudocode হলো ইংরেজি আর প্রোগ্রামিং-এর একটি মিশ্রণ। এতে আপনি semicolon, bracket ইত্যাদি নিয়ে চিন্তা না করেই শুধু লজিকটি লিখে রাখতে পারেন। পরে সহজেই এটিকে আসল কোডে রূপান্তর করা যায়।
Example — Find the Maximum of an Array
ALGORITHM find_max(A, n):
  max ← A[0]
  FOR i FROM 1 TO n - 1:
      IF A[i] > max:
          max ← A[i]
  RETURN max

Now the same idea in real C. You can run it right here:

find_max.c
#include <stdio.h>

int find_max(int A[], int n) {
    int max = A[0];
    for (int i = 1; i < n; i++) {
        if (A[i] > max) max = A[i];
    }
    return max;
}

int main(void) {
    int A[] = {18, 7, 42, 3, 25, 9};
    int n = sizeof(A) / sizeof(A[0]);
    printf("Maximum = %d\n", find_max(A, n));
    return 0;
}

5. Flowcharts — Thinking in Shapes

A flowchart draws an algorithm visually. Rectangles are actions, diamonds are decisions, arrows show the flow. Drawing a flowchart is often the fastest way to untangle a hard problem.

Flowchart হলো algorithm-এর একটি ছবি। আয়তক্ষেত্র দিয়ে কাজ বোঝানো হয়, হীরকাকার (diamond) দিয়ে সিদ্ধান্ত এবং তীর দিয়ে প্রবাহ (flow)। কঠিন সমস্যা বোঝার ক্ষেত্রে flowchart আঁকা অনেক সময়ই দ্রুততম পথ।
START Input x x > 0 ? (শূন্যের চেয়ে বড়?) Yes Positive No x < 0 ? (ঋণাত্মক?) Yes Negative No Zero Figure 2.2 — একটি সংখ্যা ধনাত্মক, ঋণাত্মক নাকি শূন্য তা নির্ধারণের flowchart।

Here is the same logic as runnable C code:

sign.c — stdin: -7
#include <stdio.h>

int main(void) {
    int x;
    scanf("%d", &x);

    if (x > 0)       printf("Positive\n");
    else if (x < 0)  printf("Negative\n");
    else              printf("Zero\n");

    return 0;
}

6. Loop Invariants — The Secret of Correctness

A loop invariant is a statement that remains true before the loop, after every iteration, and still true when the loop ends. It is the single most powerful tool for proving that code is correct.

Loop invariant হলো এমন একটি শর্ত যা — লুপ শুরুর আগে, প্রতিটি iteration-এর পরে এবং লুপ শেষ হওয়ার পরেও — সবসময় সত্য থাকে। এটি কোডের শুদ্ধতা প্রমাণের সবচেয়ে গুরুত্বপূর্ণ হাতিয়ার।
Proof Template (1) Show the invariant holds before the loop starts.
(2) Show: if it holds before iteration k, it still holds after iteration k.
(3) Combine with the termination condition to conclude correctness.

(১) লুপ শুরুর আগে invariant সত্য প্রমাণ করুন।
(২) প্রমাণ করুন: iteration k-এর আগে সত্য থাকলে, k-এর পরেও সত্য থাকে।
(৩) Termination শর্তের সাথে মিলিয়ে চূড়ান্ত শুদ্ধতা প্রমাণ করুন।

Example: For find_max above, the invariant is — "At the start of iteration i, max equals the maximum of A[0..i-1]."

  1. Before loop (i = 1): max = A[0]. Maximum of A[0..0] is A[0] itself. ✓
  2. Step: if A[i] > max, we update max to A[i]. So max = maximum of A[0..i]. ✓
  3. After loop (i = n): max = maximum of A[0..n-1] — which is our answer. ✓

7. Mathematical Induction — Recursion's Twin

Mathematical induction proves a statement P(n) holds for all natural numbers n by two steps:

  • Base case: Prove P(0) or P(1).
  • Inductive step: Assume P(k). Prove P(k + 1).
গাণিতিক induction একটি statement P(n) সব natural number-এর জন্য সত্য প্রমাণ করে দুটি ধাপে — Base case-এ P(0) বা P(1) সত্য প্রমাণ করা হয়; Inductive step-এ ধরে নেওয়া হয় P(k) সত্য, এবং সেখান থেকে P(k+1) প্রমাণ করা হয়।
Classic Theorem 1 + 2 + 3 + ... + n = n(n+1) / 2

Verify it with code — Gauss's formula vs. a direct loop:

gauss.c
#include <stdio.h>

int main(void) {
    int n = 100;

    // Method 1 — direct loop
    long sum_loop = 0;
    for (int i = 1; i <= n; i++) sum_loop += i;

    // Method 2 — Gauss's formula
    long sum_formula = (long)n * (n + 1) / 2;

    printf("Sum by loop    = %ld\n", sum_loop);
    printf("Sum by formula = %ld\n", sum_formula);
    printf("Match: %s\n", sum_loop == sum_formula ? "YES" : "NO");
    return 0;
}

8. Decomposition in Practice — A Real Problem

Problem: Given a list of exam scores, find the average of the top 3.

সমস্যা: একটি পরীক্ষার স্কোরের তালিকা থেকে সর্বোচ্চ ৩টি স্কোরের গড় বের করতে হবে।

Beginner reaction: "just write some code". Professional reaction: decompose first.

Step 1 — What do I need?
  input  : array of scores, length n
  output : a single number = average of top 3

Step 2 — Break into subproblems
  (a) sort the array in descending order
  (b) take the first 3 elements
  (c) compute the average

Step 3 — Have I solved these before?
  - sorting      → yes (qsort library function)
  - pick first 3 → trivial indexing
  - average      → sum / 3

Once decomposed, coding is almost mechanical:

top3_avg.c
#include <stdio.h>
#include <stdlib.h>

int cmp_desc(const void *a, const void *b) {
    return *(const int*)b - *(const int*)a;
}

int main(void) {
    int scores[] = {72, 98, 65, 90, 54, 88, 77};
    int n = sizeof(scores) / sizeof(scores[0]);

    qsort(scores, n, sizeof(int), cmp_desc);

    double avg = (scores[0] + scores[1] + scores[2]) / 3.0;
    printf("Top 3: %d, %d, %d\n", scores[0], scores[1], scores[2]);
    printf("Average of top 3 = %.2f\n", avg);
    return 0;
}

9. Abstraction — The Mental Superpower

When you call printf, you do not care how the bytes reach your terminal. You just call it. That is abstraction: hiding irrelevant detail behind a clean interface.

printf কল করার সময় আপনি জানেন না byte গুলো আসলে কীভাবে terminal-এ পৌঁছায় — আপনি শুধু ফাংশনটিই কল করেন। এটিই abstraction: অপ্রয়োজনীয় বিস্তারিত লুকিয়ে রেখে একটি পরিষ্কার interface প্রদান করা।
LayerDeals withHides from you
Your C codeLogic, data—
printfFormattingHow bytes are written
C standard librarySystem callsSyscall numbers
OS kernelHardware driversPort numbers, interrupts
CPUInstructionsTransistors, silicon

10. Practice Problems

প্রথমে নিজে চেষ্টা করুন। এরপর Show Answer চাপলে উত্তর দেখা যাবে এবং তা সরাসরি এখান থেকেই রান করে যাচাই করা যাবে।
  1. Write pseudocode to reverse an array of integers in place, without using a second array.
    একটি int array কে in-place (দ্বিতীয় array ছাড়াই) reverse করার pseudocode লিখুন।
    ✨ Show Answer (উত্তর দেখুন)
    ALGORITHM reverse(A, n):
      i ← 0
      j ← n - 1
      WHILE i < j:
          swap(A[i], A[j])
          i ← i + 1
          j ← j - 1

    Now the runnable C version:

    reverse.c
    #include <stdio.h>
    
    void reverse(int A[], int n) {
        int i = 0, j = n - 1;
        while (i < j) {
            int t = A[i]; A[i] = A[j]; A[j] = t;
            i++; j--;
        }
    }
    
    int main(void) {
        int A[] = {1, 2, 3, 4, 5};
        int n = 5;
        reverse(A, n);
        for (int i = 0; i < n; i++) printf("%d ", A[i]);
        printf("\n");
        return 0;
    }
  2. Write a C program that solves FizzBuzz for N = 15 — print "Fizz" for multiples of 3, "Buzz" for 5, "FizzBuzz" for both, else the number.
    N = 15 পর্যন্ত FizzBuzz সমাধান করুন — ৩-এর গুণিতক হলে "Fizz", ৫-এর গুণিতক হলে "Buzz", দুটোই হলে "FizzBuzz", নতুবা সংখ্যাটি প্রিন্ট করুন।
    ✨ Show Answer (উত্তর দেখুন)
    fizzbuzz.c
    #include <stdio.h>
    
    int main(void) {
        for (int i = 1; i <= 15; i++) {
            if      (i % 15 == 0) printf("FizzBuzz\n");
            else if (i %  3 == 0) printf("Fizz\n");
            else if (i %  5 == 0) printf("Buzz\n");
            else                printf("%d\n", i);
        }
        return 0;
    }
  3. For the function that computes the sum of an array, state a loop invariant and argue briefly why it holds.
    একটি array-র যোগফল বের করার ফাংশনের জন্য একটি loop invariant লিখুন এবং ব্যাখ্যা করুন কেন এটি সত্য থাকে।
    ✨ Show Answer (উত্তর দেখুন)

    Invariant: At the start of iteration i, the variable s equals A[0] + A[1] + ... + A[i-1].

    Why it holds: Before the loop (i = 0), s = 0, which is the empty sum — true. In each step we add A[i] and increment i, so after the step s becomes A[0] + ... + A[i]. When i = n, s equals the total sum.

    Invariant: iteration i-এর শুরুতে s-এর মান সমান A[0] + A[1] + ... + A[i-1]।
    কেন সত্য: লুপের শুরুতে (i = 0) s = 0 — শূন্য যোগফল, সত্য। প্রতিটি iteration-এ A[i] যোগ হয় এবং i বাড়ে, ফলে iteration শেষে s = A[0] + ... + A[i]। সবশেষে i = n হলে s পুরো array-র যোগফল হবে।

  4. Prove by induction that 2⁰ + 2¹ + ... + 2ⁿ = 2ⁿ⁺¹ − 1.
    Induction ব্যবহার করে প্রমাণ করুন: 2⁰ + 2¹ + ... + 2ⁿ = 2ⁿ⁺¹ − 1।
    ✨ Show Answer (উত্তর দেখুন)

    Base (n = 0): Left side = 2⁰ = 1. Right side = 2¹ − 1 = 1. ✓

    Inductive step: Assume it holds for some k ≥ 0, i.e., 2⁰ + 2¹ + ... + 2ᵏ = 2ᵏ⁺¹ − 1. Then for k + 1:

    2⁰ + 2¹ + ... + 2ᵏ + 2ᵏ⁺¹
      = (2ᵏ⁺¹ − 1) + 2ᵏ⁺¹       (by hypothesis)
      = 2 · 2ᵏ⁺¹ − 1
      = 2ᵏ⁺² − 1                  ✓

    Verify with code:

    pow2_sum.c
    #include <stdio.h>
    
    int main(void) {
        long sum = 0, pow = 1;
        int n = 10;
        for (int i = 0; i <= n; i++) { sum += pow; pow *= 2; }
        printf("2^0 + ... + 2^%d = %ld\n", n, sum);
        printf("Formula 2^%d - 1  = %ld\n", n + 1, pow - 1);
        return 0;
    }
  5. You already know how to find the maximum of an array. How would you reuse that pattern to find the second maximum?
    আপনি ইতিমধ্যে array-র maximum বের করা জানেন। একই pattern ব্যবহার করে দ্বিতীয় সর্বোচ্চ মান কীভাবে বের করবেন?
    ✨ Show Answer (উত্তর দেখুন)

    Keep two variables — max and second. Walk the array once: when a new element beats max, push max into second and update max. If it is only bigger than second but not max, update second.

    দুটি variable রাখুন — max ও second। Array একবার স্ক্যান করুন: কোনো মান max-এর চেয়ে বড় হলে পুরনো max-কে second-এ সরিয়ে নতুন মানকে max বানান। মানটি যদি শুধু second-এর চেয়ে বড় হয় কিন্তু max-এর চেয়ে ছোট, তাহলে second আপডেট করুন।

    second_max.c
    #include <stdio.h>
    #include <limits.h>
    
    int main(void) {
        int A[] = {18, 7, 42, 3, 25, 42, 9};
        int n = sizeof(A) / sizeof(A[0]);
    
        int max = INT_MIN, second = INT_MIN;
        for (int i = 0; i < n; i++) {
            if (A[i] > max)              { second = max; max = A[i]; }
            else if (A[i] > second && A[i] < max) { second = A[i]; }
        }
        printf("Max = %d, Second max = %d\n", max, second);
        return 0;
    }
  6. Describe your mobile phone as a stack of at least 4 abstraction layers, from hardware to apps.
    আপনার মোবাইল ফোনকে কমপক্ষে ৪টি abstraction স্তরে ভাগ করে দেখান — hardware থেকে app পর্যন্ত।
    ✨ Show Answer (উত্তর দেখুন)

    One reasonable answer:

    1. Hardware — CPU, RAM, screen, battery.
    2. Firmware / drivers — talks to each hardware component.
    3. Operating System (Android / iOS) — manages processes, memory, files.
    4. Frameworks — provide UI widgets, networking APIs.
    5. Apps (WhatsApp, Facebook, etc.) — what you actually see.

    উপরের প্রতিটি স্তর নিচের স্তরের বিস্তারিত লুকিয়ে রেখে একটি পরিষ্কার interface দেয় — এটিই abstraction।

  7. You want the GPA across 40 courses. Break the problem into 4 or more subproblems (decomposition).
    ৪০টি কোর্সের GPA হিসাব করতে চান। সমস্যাটিকে ৪টি বা তার বেশি উপ-সমস্যায় ভাগ করুন।
    ✨ Show Answer (উত্তর দেখুন)
    1. Read each course's grade and credit hour (input).
    2. Convert each letter grade to a grade point (e.g., A = 4.00, A− = 3.70, …).
    3. For each course, compute (grade point × credit).
    4. Sum those values to get total quality points.
    5. Sum credits to get total credit hours.
    6. GPA = total quality points ÷ total credit hours.

    প্রতিটি ছোট ধাপ আলাদাভাবে সহজ — সমস্যাটিকে এভাবে ভাঙলে সমাধান পরিষ্কার হয়ে যায়।

  8. Check each of the 5 algorithm properties (finiteness, definiteness, input, output, effectiveness) on the "make tea" procedure. Fix any that fail.
    আপনার চা বানানোর পদ্ধতির ওপর algorithm-এর ৫টি বৈশিষ্ট্য (finiteness, definiteness, input, output, effectiveness) যাচাই করুন। যেকোনো ফাঁক থাকলে ঠিক করুন।
    ✨ Show Answer (উত্তর দেখুন)

    Finiteness: yes — 6 steps. Definiteness: weak — "wait 3 minutes" is OK, but "add sugar" should say how much. Fix: "add 2 teaspoons of sugar". Input: implicit — water, tea leaves, sugar, milk. Fix: state them explicitly. Output: yes — a cup of tea. Effectiveness: yes — every step is doable.

    সবগুলো পরীক্ষা করলেই বোঝা যায় যে ছোট ছোট সংশোধন করলে চা বানানোর পদ্ধতিটিও একটি সম্পূর্ণ algorithm হয়ে ওঠে।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
AlgorithmA finite, unambiguous sequence of steps that solves a problem.সসীম ও সুনির্দিষ্ট ধাপের ক্রম, যা একটি সমস্যা সমাধান করে।
Computational ThinkingThe mental discipline of formulating problems so that a computer can solve them.সমস্যাকে এমনভাবে সাজানো, যাতে কম্পিউটার সেটি সমাধান করতে পারে।
DecompositionBreaking a big problem into smaller, manageable parts.বড় সমস্যাকে ছোট অংশে ভেঙে ফেলা।
Pattern RecognitionSpotting similarities between problems you have already solved.আগে সমাধান করা সমস্যার সাথে মিল খুঁজে বের করা।
AbstractionHiding unimportant detail to focus on the essence.অপ্রয়োজনীয় বিস্তার আড়াল করে মূল ধারণায় মনোযোগ দেওয়া।
PseudocodePlain-language description of an algorithm — half English, half code.অ্যালগরিদমের সাধারণ ভাষায় বর্ণনা — অর্ধেক ইংরেজি, অর্ধেক কোড।
FlowchartA diagram of an algorithm using boxes and arrows.বক্স ও অ্যারো দিয়ে অ্যালগরিদমের চিত্র।
Loop InvariantA condition that is true before and after every iteration of a loop.প্রতিটি iteration-এর আগে ও পরে যে শর্ত সত্য থাকে।
InductionProof technique: prove a base case, then prove each step from the previous.প্রমাণের কৌশল — base case প্রমাণ করে ধাপে ধাপে এগোনো।
Trace TableA table that records the value of each variable at each step.প্রতিটি ধাপে variable-এর মান রেকর্ড করার টেবিল।

Summary — Module 02

Programming is thinking first, typing last. The four pillars — decomposition, pattern recognition, abstraction, algorithmic thinking — are your mental toolkit. Pseudocode and flowcharts are your scratch pad. Loop invariants and induction are your proof tools. Internalize these and C becomes just a language for writing down what you already figured out.

প্রোগ্রামিং মানে — আগে চিন্তা, পরে টাইপ। চারটি স্তম্ভ (decomposition, pattern, abstraction, algorithmic thinking) আপনার মানসিক হাতিয়ার। Pseudocode ও flowchart আপনার খসড়া কাগজ। Loop invariant ও induction আপনার প্রমাণের হাতিয়ার। এগুলো আয়ত্ত করলে C শুধু সেই চিন্তাকে লিখে রাখার একটি ভাষা মাত্র।

Next Module → Setting up the toolchain — GCC, Clang, VS Code and the compilation pipeline.