Skip to content

001 — Even or Odd

এটা তোমার এই repo-র একদম প্রথম problem note — অভিনন্দন, শুরু হয়ে গেল! ধীরে পড়ো, তাড়া নেই। এই একটা problem-এর হাত ধরেই আমরা % (modulo) operator-এর সাথে বন্ধুত্ব করব, যেটা পরের পুরো level জুড়ে বারবার ফিরবে। "vule gesi" — কোনো ব্যাপার না, এই note ধরে ধরে আবার গেঁথে যাবে।

Source

  • Original source: Classic beginner exercise (related practice: Codeforces 4A — Watermelon — https://codeforces.com/problemset/problem/4/A)
  • Platform: Classic exercise / Codeforces (related)
  • Topic: Math-based programming fundamentals → Level 0: Absolute Basics
  • Difficulty: Easy
  • Pattern: parity / last bit
  • Basic idea inherited from: — (এটাই শুরুর শিকড়, আগে কিছু নেই)

1. Problem in simple words

একটা integer n দেওয়া আছে। বলতে হবে সেটা even (জোড় সংখ্যা) নাকি odd (বিজোড় সংখ্যা)। ব্যস, এটুকুই।

মনে করিয়ে দিই:

  • even = 2 দিয়ে নিঃশেষে ভাগ যায় — যেমন 0, 2, 4, 6, 8, 10, ...
  • odd = 2 দিয়ে ভাগ করলে 1 বাকি থাকে — যেমন 1, 3, 5, 7, 9, ...

দেখতে তুচ্ছ, কিন্তু interview-তে এই একটা চেক bug-free আর চোখের নিমেষে লিখতে পারাটাই আসল target। তাই ছোট বলে উড়িয়ে দিও না — এটা দিয়েই আমরা চিন্তা করার অভ্যাসটা তৈরি করব।

2. What is the math idea?

মূল idea একটাই — remainder। কোনো সংখ্যাকে 2 দিয়ে ভাগ করলে যা বাকি থাকে, সেটাই বলে দেয় even না odd।

Python-এ remainder বের করার operator হলো % (modulo operator):

  • n % 2 == 0 → বাকি 0 → even
  • n % 2 != 0 → বাকি 1 → odd

আরেকটা চমৎকার চেহারা আছে এই idea-র — bit trick। যেকোনো সংখ্যার binary form-এ একদম শেষের bit (last bit) যদি 0 হয় সংখ্যাটা even, আর 1 হলে odd। কারণ binary-তে শুধু last bit-ই 1-এর ঘর; বাকি সব ঘর (2, 4, 8, ...) এমনিতেই even। তাই n % 2 আর n & 1 (last bit পড়া) — দুটো একই উত্তর দেয়।

3. Which basic idea does this inherit from?

এটা পুরো repo-র প্রথম problem, তাই এর উপরে দাঁড়ানোর মতো আগের কোনো problem নেই (তাই "inherited from: —")।

বরং উল্টোটা — এটাই সেই বীজ যেখান থেকে অনেক কিছু গজাবে। এখানে শেখা % operator আর "পুরো সংখ্যা না দেখে শুধু শেষটা দেখা" — এই দুই idea সরাসরি কাজে লাগবে:

  • 002 (Sum of Digits)% 2-এর বদলে % 10 দিয়ে last digit ছোঁয়া
  • 008 (Find Last Digit) — সেই % 10-এরই সরাসরি প্রয়োগ

মানে আজ তুমি শুধু even/odd শিখছ না — তুমি % operator-এর সাথে প্রথম পরিচয় করছ।

4. Real-life analogy

ভাবো তোমার কাছে n জোড়া জুতো নেই — n টা জুতো আছে, এলোমেলো। তুমি জোড়ায় জোড়ায় (২টা করে) সাজিয়ে রাখছ।

  • সব জুতো সুন্দর জোড়া হয়ে গেল, একটাও একা পড়ে রইল না → সংখ্যাটা even
  • সব সাজানোর পরেও একটা জুতো একা পড়ে রইল, তার জোড়া নেই → সংখ্যাটা odd

সেই "একা পড়ে থাকা জুতো"-টাই হলো remainder। even-এ remainder 0 (কেউ একা নেই), odd-এ remainder 1 (একজন একা)। n % 2 আসলে তোমাকে বলছে — "সব জোড়া বাঁধার পর হাতে ক'টা একা রইল?"

5. Visual explanation

প্রথমে number line-এ even আর odd কীভাবে এক-একটা করে পালা করে আসে, সেটা দেখো:

even/odd একটার পর একটা পালা করে আসে (number line)

  0    1    2    3    4    5    6    7    8
  E    O    E    O    E    O    E    O    E
  |    |    |    |    |    |    |    |    |
 জোড় বিজোড় জোড় বিজোড় জোড় বিজোড় জোড় বিজোড় জোড়

E = even (n % 2 = 0),  O = odd (n % 2 = 1)

এবার সেই bit-এর ছবি — last bit-টাই পুরো গল্প বলে দেয়:

binary form-এ শুধু শেষ ঘরটা (last bit) দেখলেই চলে

  6  = 1 1 0   <- last bit 0  -> even
  7  = 1 1 1   <- last bit 1  -> odd
 12  = 1 1 0 0 <- last bit 0  -> even
 13  = 1 1 0 1 <- last bit 1  -> odd
            ^
        শুধু এই ঘরটাই ঠিক করে even না odd

লক্ষ করো — পুরো সংখ্যাটা কত বড় তাতে কিছু এসে যায় না, শুধু শেষ জায়গাটা গুরুত্বপূর্ণ। এই "শেষটা দেখো" idea-টা মনে রাখো, পরের problem-এ ফিরবে।

6. Example input and output

input  ->  output
-----------------
   4   ->  even      (4 % 2 = 0)
   7   ->  odd       (7 % 2 = 1)
   0   ->  even      (0 % 2 = 0, শূন্যও জোড়!)
  10   ->  even
  99   ->  odd
  -3   ->  odd       (Python-এ -3 % 2 = 1)
  -4   ->  even

দুটো জিনিস খেয়াল করো: 0 হলো even (অনেকে ভুল করে), আর negative সংখ্যাও even/odd হয় — minus চিহ্ন parity বদলায় না।

7. Brute force thinking

প্রথমবার ভাবলে, % operator মাথায় না-ও আসতে পারে। তখন "হাতে গুনে" করার মতো একটা পদ্ধতি মনে আসে — সংখ্যাটা থেকে বারবার 2 করে বিয়োগ করতে থাকো, যতক্ষণ না 0 বা 1-এ পৌঁছাও:

def even_or_odd_brute(n):
    n = abs(n)          # negative-কে আগে positive বানিয়ে নিই
    while n > 1:
        n -= 2          # এক জোড়া সরিয়ে রাখলাম
    return "even" if n == 0 else "odd"

এটা আসলে আমাদের জুতো-জোড়ার analogy-টাই — একটা একটা জোড়া (2টা) সরিয়ে রাখছি, শেষে হাতে 0 থাকলে even, 1 থাকলে odd। ঠিক উত্তরই দেয়।

8. Why brute force may be slow

সমস্যা হলো এই loop-টা n / 2 বার ঘোরে। ছোট সংখ্যায় টের পাবে না, কিন্তু n যদি 1,000,000,000 হয়, তাহলে loop প্রায় 50 কোটি বার চলবে — interview-তে এটা Time Limit Exceeded।

n = 1000000000 হলে:
  brute force: ~500000000 বার loop  (ধীর, O(n))
  smart way  : ঠিক 1 বার %         (চোখের নিমেষে, O(1))

মূল শিক্ষা: যেটা এক ধাপে জানা যায়, সেটার জন্য loop চালানো অপচয়। আমাদের কাছে তো সেই এক-ধাপের tool আছে — %

9. Better thinking

পুরো জোড়া বাঁধার নাটক বাদ — সরাসরি জিজ্ঞেস করি "2 দিয়ে ভাগ করলে কত বাকি?" সেটাই n % 2

def even_or_odd(n):
    return "even" if n % 2 == 0 else "odd"

একটাই operation, সংখ্যা যত বড়ই হোক। এটাই O(1) — constant time। brute force-এর 50 কোটি ধাপ এক ধাপে নেমে এল।

10. Thinking tweak

আসল "আহা!" মুহূর্তটা এই — পুরো সংখ্যাটা দেখার দরকারই নেই, শুধু শেষটা দেখলেই চলে।

  • দশমিক চোখে: সংখ্যার last digit যদি 0, 2, 4, 6, 8 হয় → even; 1, 3, 5, 7, 9 হলে → odd। তাই 9,999,998 even কিনা জানতে পুরোটা পড়ার দরকার নেই — শেষ 8 দেখলেই হলো।
  • binary চোখে: last bit 0 হলে even, 1 হলে odd → এটাই n & 1

এই "শেষ digit / শেষ bit-ই যথেষ্ট" tweak-টা মাথায় গেঁথে নাও। 002-এ আমরা এই last-digit ছোঁয়ার idea-কেই % 10 দিয়ে কাজে লাগাব।

11. Step-by-step dry run

চলো n = 7 ধীরে ধীরে চালাই। আগে brute force (জোড়া বাঁধা) — যাতে কেন কাজ করে সেটা চোখে দেখা যায়:

step n (শুরুতে) n > 1? n -= 2 হাতে রইল
1 7 হ্যাঁ 7 - 2 = 5 5
2 5 হ্যাঁ 5 - 2 = 3 3
3 3 হ্যাঁ 3 - 2 = 1 1
4 1 না (loop থামল) 1

শেষে হাতে রইল 1 → একজন একা → odd। তিনবার জোড়া বাঁধলাম, একটা একা পড়ে রইল।

এবার smart way — এক লাইনেই:

7 % 2  ->  7 = 2×3 + 1  ->  remainder 1  ->  odd

দেখো, brute force-এর 4 ধাপ আর %-এর 1 ধাপ — দুটোই বলছে "odd"। একই সত্য, কিন্তু % সোজা শেষ উত্তরে নিয়ে গেল।

12. Python solution

def even_or_odd(n):
    """n even হলে 'even', নাহলে 'odd' ফেরত দেয়।"""
    return "even" if n % 2 == 0 else "odd"


def is_even(n):
    """শুধু True/False চাইলে এই version।"""
    return n % 2 == 0


def is_even_bit(n):
    """একই উত্তর, কিন্তু last bit পড়ে (bit trick)।"""
    return (n & 1) == 0


# --- ছোট test গুলো (সব pass করা উচিত) ---
assert even_or_odd(4) == "even"
assert even_or_odd(7) == "odd"
assert even_or_odd(0) == "even"      # 0 জোড়
assert even_or_odd(-3) == "odd"      # Python: -3 % 2 == 1
assert even_or_odd(-4) == "even"
assert is_even(10) is True
assert is_even(11) is False
assert is_even_bit(10) is True       # bit trick-ও একই বলে
assert is_even_bit(7) is False

print(even_or_odd(4))    # even
print(even_or_odd(7))    # odd
print(even_or_odd(-3))   # odd
print("সব test pass!")

13. Line-by-line explanation

def even_or_odd(n):

একটা function বানাচ্ছি যেটা একটা সংখ্যা n নেবে।

    return "even" if n % 2 == 0 else "odd"

এটাই হৃদয়। n % 2 দেয় 2 দিয়ে ভাগের remainder। সেটা 0 হলে "even" ফেরত, নাহলে "odd"। এই A if শর্ত else B লেখাটা Python-এর ternary — "শর্ত সত্যি হলে A, নাহলে B"।

def is_even(n):
    return n % 2 == 0

কখনো string না, সরাসরি True/False দরকার হয় (যেমন বড় program-এ if-এ ব্যবহার করতে)। n % 2 == 0 নিজেই একটা True/False expression — তাই সরাসরি return করছি।

def is_even_bit(n):
    return (n & 1) == 0

n & 1 শুধু last bit-টা পড়ে: even হলে 0, odd হলে 1। তাই (n & 1) == 0 মানে even। (% আর & — দুই রাস্তা, এক গন্তব্য।)

বাকি assert লাইনগুলো নিজেদের চেক করছে — উত্তর আশানুরূপ না হলে program সেখানেই থেমে error দেবে। সব ঠিক থাকলে শেষে সব test pass! ছাপে।

14. Output walkthrough

চালালে যা ছাপবে:

even
odd
odd
সব test pass!

প্রথম তিন লাইন তিনটা print(even_or_odd(...)) থেকে: 4 → even, 7 → odd, -3 → odd। তার আগের সব assert চুপচাপ pass করেছে (assert pass করলে কিছু ছাপে না — শুধু fail করলে চিৎকার করে)। সবশেষে সব test pass! — মানে সব ঠিক আছে।

15. Time complexity

O(1) — constant time। n যত বড়ই হোক (4 হোক বা 9 ট্রিলিয়ন), একটাই % operation, একটাই তুলনা। সংখ্যার আকারের সাথে কাজ বাড়ে না।

(সূক্ষ্ম কথা: অতি-বিশাল সংখ্যায় modulo-র খরচ digit সংখ্যার সাথে সামান্য বাড়ে, কিন্তু সাধারণ interview-র মাপে আমরা একে নিশ্চিন্তে O(1) ধরি — brute force-এর O(n)-এর তুলনায় এটা আকাশ-পাতাল পার্থক্য।)

16. Space complexity

O(1) — কোনো বাড়তি list, string বা array লাগছে না; শুধু গুটিকয় variable। input ছাড়া আলাদা জায়গা প্রায় শূন্য।

17. Common mistakes

  1. = আর == গুলিয়ে ফেলাif n % 2 = 0 লিখলে Python error দেবে। তুলনার জন্য সবসময় ==
  2. 0-কে odd ভাবা0 % 2 == 0, তাই 0 even। এটা খুব কমন ভুল।
  3. Odd চেক করতে n % 2 == 1 লেখা — Python-এ negative-এ এটা কাজ করে (-3 % 2 == 1), কিন্তু অভ্যাস হিসেবে n % 2 != 0 লেখা নিরাপদ, কারণ অন্য ভাষায় (C++/Java) -3 % 2 হয় -1, তখন == 1 চেক ফেল করে।
  4. negative ভুলে যাওয়া-4-ও even, -7-ও odd। minus চিহ্ন parity বদলায় না।
  5. এই জন্য string বানানো — even/odd জানতে str(n) লাগে না; % সরাসরি কাজ করে।

18. Harder problems that inherit this idea

  • Codeforces 4A — Watermelon (https://codeforces.com/problemset/problem/4/A) — পুরো problem-টাই আসলে "সংখ্যাটা even কিনা" (২-এর বেশি even হলে দুই জোড় ভাগে ভাগ করা যায়) — even/odd বোঝাই সমাধান।
  • LeetCode — Power of Two (https://leetcode.com/problems/power-of-two/) — এখানেই last-bit/bit-trick চিন্তা আরও গভীরে যায় (n & (n - 1) কৌশল)।
  • 002 (Sum of Digits) আর 008 (Find Last Digit) — এই repo-রই পরের ধাপ, যেখানে % 2-এর জায়গায় % 10 এসে last digit ছোঁবে।

19. Pattern learned

Parity check via remaindern % 2 দিয়ে even/odd, বা n & 1 দিয়ে last bit। আর তার পেছনের বড় শিক্ষা: remainder বলে দেয় "কী বাকি রইল", আর প্রায়ই গোটা সংখ্যা নয়, শুধু শেষ digit/bit দেখলেই উত্তর পাওয়া যায়। এই "শেষটা দেখো" চোখটাই পরের problem গুলোর ভিত্তি।

20. Final summary

ভবিষ্যতের আমাকে এক লাইনে: "even/odd = n % 2; remainder 0 মানে even। গোটা সংখ্যা না, শুধু শেষ digit/bit দেখলেই চলে — আর এটাই % operator-এর সাথে আমার প্রথম পরিচয়।"

পরের ধাপ → 002 — Sum of Digits (এই % idea-কে % 10 বানিয়ে last digit ছোঁব)। সম্পর্কিত → 008 — Find Last Digit

ফিরে দেখা: এই level-এর map → ../README.md · এই note-টা যে ছকে লেখা → ../../../templates/math-problem-note-template.md

21. JavaScript solution (with test cases)

JavaScript-এ % আর & দুটোই আছে, তাই code প্রায় Python-এর মতোই — কিন্তু একটা ফাঁদ আছে negative নিয়ে (নিচের টীকা)।

// n even হলে "even", নাহলে "odd"
function evenOrOdd(n) {
  return n % 2 === 0 ? "even" : "odd";
}

// শুধু boolean দরকার হলে
const isEven = (n) => n % 2 === 0;

// bit trick — last bit পড়া (n & 1)
const isEvenBit = (n) => (n & 1) === 0;

// ছোট throwing assert — fail করলে এখানেই থেমে error দেবে (Python assert-এর মতো)
const assert = (cond, msg = "") => { if (!cond) throw new Error("FAIL " + msg); };

// ---- test cases (চালাও: `node 001.js`) ----
assert(evenOrOdd(4) === "even", "4 even");
assert(evenOrOdd(7) === "odd", "7 odd");
assert(evenOrOdd(0) === "even", "0 even");      // 0 জোড়
assert(evenOrOdd(-4) === "even", "-4 even");
assert(isEven(10) === true, "10 isEven");
assert(isEvenBit(10) === true && isEvenBit(7) === false, "bit trick");
console.log("সব JS test pass!");

JS টীকা: Python-এ -3 % 2 === 1, কিন্তু JavaScript-এ -3 % 2 === -1 (remainder dividend-এর sign নেয়)। তাই odd চেক করতে কখনো n % 2 === 1 লিখো না — n % 2 !== 0 লেখো, সব sign-এ নিরাপদ। n & 1 অবশ্য negative-এও 0/1 দেয়, তাই bit trick আরও robust।

22. TypeScript solution (with test cases)

type Parity = "even" | "odd"; // union type — return শুধু এই দুটোই হতে পারে

function evenOrOdd(n: number): Parity {
  return n % 2 === 0 ? "even" : "odd";
}

const isEven = (n: number): boolean => n % 2 === 0;

// ---- ছোট test helper + cases ----
function expect<T>(actual: T, expected: T, msg = ""): void {
  if (actual !== expected) throw new Error(`FAIL ${msg}: got ${actual}`);
}
expect(evenOrOdd(4), "even", "4");
expect(evenOrOdd(7), "odd", "7");
expect(evenOrOdd(0), "even", "0");
expect(evenOrOdd(-4), "even", "-4");
expect(isEven(11), false, "11");
console.log("সব TS test pass!");

TS টীকা: return type Parity ("even" | "odd") দিলে ভুল string (যেমন "Even" বা typo) compile-time-এই ধরা পড়ে। high-end codebase-এ এভাবে "অসম্ভব অবস্থা" type দিয়ে আটকানোকে বলে making illegal states unrepresentable — bug কমানোর সবচেয়ে শক্তিশালী অভ্যাসগুলোর একটা।

23. কোথায় কাজে লাগে (real-world use)

Parity check (% 2 / & 1) দেখতে তুচ্ছ, কিন্তু production code-এ সর্বত্র:

  • UI — zebra striping: table/list-এ alternate row রং দিতে index % 2 (even/odd row), পড়া সহজ করে।
  • Sharding / load balancing: request বা user-id কে id % N দিয়ে N-টা server/partition-এ ভাগ করা; even/odd হলো এর সবচেয়ে সরল রূপ (N = 2)।
  • Round-robin scheduling: পালা করে কাজ ভাগ — turn even না odd দেখে।
  • Error detection: parity bit — data-র 1-এর সংখ্যা even/odd রাখার মাধ্যমে transmission error ধরা (networking, memory)।
  • Graphics/animation: frame number even/odd দেখে alternate behaviour (double-buffering, flicker effect)।

মূল pattern — "পুরোটা না দেখে শুধু শেষ bit/digit দেখা" — hashing, checksum, round-robin, bloom filter সবখানে ফিরে আসে।


মনে রাখার নিয়ম (legal): সব নিজের ভাষায় লেখা; problem statement copy করা হয়নি; official link শুধু attribution-এর জন্য; "asked by Google/Amazon" এমন দাবি করা হয়নি — বরং "common interview pattern" লেখা।