# 001 — Even or Odd

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

<div class="problem-source" markdown="1">

<p class="source-label" id="source">Problem link ও উৎস</p>

- 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: — (এটাই শুরুর শিকড়, আগে কিছু নেই)

</div>

## প্রশ্ন ও উদাহরণ {#problem}

### সহজ করে প্রশ্ন {#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। তাই ছোট বলে উড়িয়ে দিও না — এটা দিয়েই আমরা চিন্তা করার অভ্যাসটা তৈরি করব।

### Input ও output {#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 বদলায় না।

### চেনা উদাহরণে বোঝা {#4-real-life-analogy}

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

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

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

## ভিত্তির ধারণা {#idea}

### আগের কোন ধারণাটি লাগবে {#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-এর সাথে প্রথম পরিচয় করছ।

### ভেতরের অঙ্ক {#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 পড়া) — দুটো একই উত্তর দেয়।

## ধাপে ধাপে সমাধান {#walkthrough}

### প্রথম সরল উপায় {#7-brute-force-thinking}

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

```python
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`।

```python
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` দিয়ে কাজে লাগাব।

### ছবিতে বোঝা {#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-এ ফিরবে।

### ছোট input-এ ধাপে ধাপে {#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"। একই সত্য, কিন্তু `%` সোজা শেষ উত্তরে নিয়ে গেল।

## কোড ও ব্যাখ্যা {#code}

### Python {#12-python-solution}

```python
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!` ছাপে।

### Output মিলিয়ে দেখা {#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!` — মানে সব ঠিক আছে।

### JavaScript ও test cases {#21-javascript-solution-with-test-cases}

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

```javascript
// 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।

### TypeScript ও test cases {#22-typescript-solution-with-test-cases}

```typescript
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 কমানোর সবচেয়ে শক্তিশালী অভ্যাসগুলোর একটা।

## খরচ ও সাধারণ ভুল {#cost}

### সময় {#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)` লাগে না; `%` সরাসরি কাজ করে।

## শেখা ও পরের অনুশীলন {#practice}

### এই ধারণার পরের অনুশীলন {#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](002-sum-of-digits.md) (এই `%` idea-কে `% 10` বানিয়ে last digit ছোঁব)। সম্পর্কিত → [008 — Find Last Digit](008-find-last-digit.md)।

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

### কোথায় কাজে লাগে {#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" লেখা।
