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 → evenn % 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।
একটাই 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 — এক লাইনেই:
দেখো, 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¶
একটা function বানাচ্ছি যেটা একটা সংখ্যা n নেবে।
এটাই হৃদয়। n % 2 দেয় 2 দিয়ে ভাগের remainder। সেটা 0 হলে "even" ফেরত, নাহলে "odd"। এই A if শর্ত else B লেখাটা Python-এর ternary — "শর্ত সত্যি হলে A, নাহলে B"।
কখনো string না, সরাসরি True/False দরকার হয় (যেমন বড় program-এ if-এ ব্যবহার করতে)। n % 2 == 0 নিজেই একটা True/False expression — তাই সরাসরি return করছি।
n & 1 শুধু last bit-টা পড়ে: even হলে 0, odd হলে 1। তাই (n & 1) == 0 মানে even। (% আর & — দুই রাস্তা, এক গন্তব্য।)
বাকি assert লাইনগুলো নিজেদের চেক করছে — উত্তর আশানুরূপ না হলে program সেখানেই থেমে error দেবে। সব ঠিক থাকলে শেষে সব test pass! ছাপে।
14. Output walkthrough¶
চালালে যা ছাপবে:
প্রথম তিন লাইন তিনটা 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¶
=আর==গুলিয়ে ফেলা —if n % 2 = 0লিখলে Python error দেবে। তুলনার জন্য সবসময়==।- 0-কে odd ভাবা —
0 % 2 == 0, তাই 0 even। এটা খুব কমন ভুল। - Odd চেক করতে
n % 2 == 1লেখা — Python-এ negative-এ এটা কাজ করে (-3 % 2 == 1), কিন্তু অভ্যাস হিসেবেn % 2 != 0লেখা নিরাপদ, কারণ অন্য ভাষায় (C++/Java)-3 % 2হয়-1, তখন== 1চেক ফেল করে। - negative ভুলে যাওয়া —
-4-ও even,-7-ও odd। minus চিহ্ন parity বদলায় না। - এই জন্য 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 remainder — n % 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" লেখা।