008 — Find Last Digit¶
001-এ তুমি
% 2দিয়ে last bit ছুঁয়েছিলে, 002-এ% 10দিয়ে last digit তুলে যোগ করেছিলে। আজকের problem সেই% 10-এরই সবচেয়ে সরল, সবচেয়ে খাঁটি রূপ — শুধু একটা last digit চাই, যোগ-গুণ কিছু না। ছোট মনে হবে, কিন্তু এই এক লাইনের idea-টা পরের অনেক জায়গায় (unit digit of power, cyclicity) মাথা তুলবে। তাই হালকা ভেবে উড়িয়ে দিও না।
Source¶
- Original source: Classic beginner exercise
- Platform: Classic exercise
- Topic: Math-based programming fundamentals → Level 0: Absolute Basics
- Difficulty: Easy
- Pattern: mod 10
- Basic idea inherited from: 001 (Even or Odd)
1. Problem in simple words¶
একটা integer n দেওয়া আছে। তার last digit (সবচেয়ে ডানদিকের সংখ্যাটা) বের করতে হবে। ব্যস, এটুকুই।
যেমন 1234-এর last digit 4, 7-এর last digit 7, 90-এর last digit 0।
দেখতে তুচ্ছ, কিন্তু এটাই digit নিয়ে কাজের একদম ভিত্তি — last digit তুলতে পারা মানে digit extraction-এর প্রথম ইট গাঁথা।
2. What is the math idea?¶
মূল idea একটাই — remainder by 10। কোনো সংখ্যাকে 10 দিয়ে ভাগ করলে যা বাকি থাকে, সেটাই তার last digit।
Python-এ:
কেন? কারণ আমরা base-10 (দশমিক) system-এ লিখি। 1234 মানে আসলে 1×1000 + 2×100 + 3×10 + 4×1। প্রথম তিনটা term-ই 10 দিয়ে নিঃশেষে ভাগ যায় (1000, 100, 10 সবই 10-এর গুণিতক), তাই 10 দিয়ে ভাগ করলে শুধু শেষের 4 বাকি থাকে। মানে last digit হলো সেই অংশ যেটা 10-এর ঘরে আঁটে না।
3. Which basic idea does this inherit from?¶
সরাসরি 001 (Even or Odd) থেকে।
001-এ আমরা শিখেছিলাম — পুরো সংখ্যা না দেখে শুধু শেষটা দেখলেই চলে, আর সেই শেষটা ধরিয়ে দেয় % operator। শুধু 001-এ আমরা 2 দিয়ে ভাগ করে last bit দেখতাম; এখানে 10 দিয়ে ভাগ করে last digit দেখছি:
001: n % 2 -> last bit (even/odd)
008: n % 10 -> last digit (একই "শেষ ছোঁয়ার" চিন্তা, base বদলে গেছে মাত্র)
আর 002-এর সাথেও আত্মীয়তা গভীর: 002-এ এই % 10 একটা loop-এর ভেতরে বসে সব digit তুলত। 008 হলো সেই loop-এর প্রথম পদক্ষেপ — মাত্র একবার % 10। মানে 002 জানলে 008 এমনিই পারো; আবার 008 না বুঝলে 002-এর loop-ও আবছা থাকবে।
4. Real-life analogy¶
ভাবো একটা লম্বা train, পেছন থেকে দেখছ। তোমার শুধু শেষ বগি-টা দরকার — সামনের ইঞ্জিন বা মাঝের বগি ক'টা, সে নিয়ে মাথা ঘামানোর দরকার নেই।
- পুরো train = পুরো সংখ্যা
1234 - শেষ বগি = last digit
4 - "শেষ বগিটা কোনটা?" — এই প্রশ্নের উত্তর এক ঝলকেই দেওয়া যায়, পুরো train মাপতে হয় না
n % 10 আসলে তোমাকে সরাসরি সেই শেষ বগিটাই এনে দেয় — train কত লম্বা তা না গুনেই।
5. Visual explanation¶
1234-কে digit-এর বাক্স ভাবো; last digit মানে একদম ডানের বাক্সটা:
কেন % 10 ঠিক ওই বাক্সটাই দেয়, place value দিয়ে দেখো:
1234 = 1×1000 + 2×100 + 3×10 + 4×1
\________________/ \_/
এই অংশ 10 দিয়ে ভাগ যায় এই 4 বাকি থাকে
(1230, পুরোটা 10-এর গুণিতক) -> তাই last digit
লক্ষ করো — সংখ্যাটা কত বড় তাতে কিছু আসে যায় না, 10-এর ঘরে আঁটে না এমন শেষ অংশটাই উত্তর।
6. Example input and output¶
input -> output (কীভাবে)
------------------------------
1234 -> 4 (1234 % 10)
7 -> 7 (একটাই digit, সে-ই last)
0 -> 0 (0 % 10 = 0)
90 -> 0 (শেষে শূন্য, last digit 0)
100 -> 0
-1234 -> 4 (চিহ্ন বাদ দিয়ে digit-ই চাই)
দুটো জিনিস খেয়াল করো: শেষে শূন্য থাকলে last digit 0 (যেমন 90, 100), আর negative সংখ্যায় আমরা সাধারণত চিহ্ন বাদ দিয়ে digit-টাই চাই (নিচে section 17-এ Python-এর %-এর খটকা আছে — তাই abs() নিরাপদ)।
7. Brute force thinking¶
% 10-এর কথা যদি মাথায় না আসে? তখন "হাতে গুনে" করার পথ — সংখ্যাটাকে string বানিয়ে শেষ অক্ষরটা তুলে আনি:
এটা কাজ করে, ঠিক উত্তর দেয়, পড়তেও সহজ। আরেকটা আরও "সৎ" কিন্তু বোকা পথ — 002-এর মতো পুরো peeling loop চালিয়ে last digit-এ পৌঁছানো, যদিও আমাদের শুধু প্রথম ধাপটাই দরকার।
8. Why brute force may be slow¶
সত্যি বলতে এখানে কোনোটাই খুব "ধীর" নয় — last digit তো এক ধাপের ব্যাপার। কিন্তু string version-এ লুকোনো খরচ আছে:
- বাড়তি জায়গা:
str(n)একটা নতুন string বানায় — O(digit) extra space।n % 10-এ সেটা লাগে না (O(1) space)। - অপ্রয়োজনীয় কাজ: শুধু শেষ digit চাই, অথচ string বানাতে গিয়ে সব digit মেমরিতে তুলছি — train-এর শেষ বগি দেখতে গোটা train কাগজে আঁকার মতো।
- ভাষা-নির্ভরতা: C++/Java-তে int → string যাওয়া-আসা ঝামেলার;
% 10যেকোনো ভাষায় এক লাইন।
n = 9999999999 হলে:
string পথ : পুরো 10 digit-এর string বানাও, তারপর শেষ অক্ষর (O(digit) space)
smart পথ : ঠিক একটা % 10 (O(1), চোখের নিমেষে)
মূল শিক্ষা: যেটা এক ধাপে জানা যায়, তার জন্য পুরো সংখ্যা ঘাঁটা অপচয়।
9. Better thinking¶
পুরো train মাপা বাদ — সরাসরি জিজ্ঞেস করি "10 দিয়ে ভাগ করলে কত বাকি?" সেটাই last digit:
একটাই operation, সংখ্যা যত বড়ই হোক। এটাই O(1) — constant time। কোনো string নেই, কোনো loop নেই।
10. Thinking tweak¶
আসল "আহা!" মুহূর্ত — last digit = n % 10, কারণ base-10-এ 10-এর সব গুণিতক (10, 100, 1000...) % 10 করলে মিলিয়ে যায়, পড়ে থাকে শুধু একক ঘরের অঙ্ক।
এই idea-টা generalize হয়:
- শেষ দুই digit চাও? →
n % 100 - শেষ তিন digit চাও? →
n % 1000 - মানে
n % 10^kদেয় শেষkটা digit।
এই "% 10^k দিয়ে শেষ k digit কাটা" tweak-টা মাথায় গেঁথে নাও — power-এর unit digit বা cyclicity-র problem-এ এটাই প্রাণ।
11. Step-by-step dry run¶
n = 1234 ধীরে চালাই — smart way তো এক লাইন, তাই আগে সেটা, পরে string পথটা মিলিয়ে দেখি:
smart way:
এক ধাপেই উত্তর 4।
এবার string পথ পাশে রেখে মিলিয়ে নিই:
| step | কী করছি | ফল |
|---|---|---|
| 1 | abs(1234) |
1234 |
| 2 | str(1234) |
"1234" |
| 3 | s[-1] (শেষ অক্ষর) |
'4' |
| 4 | int('4') |
4 |
দুই পথেই উত্তর 4 — একই সত্য, কিন্তু % 10 সোজা গন্তব্যে নিয়ে গেল, string পথ চারটে ধাপ ঘুরে।
12. Python solution¶
def last_digit(n):
"""n-এর last digit (চিহ্ন বাদ দিয়ে) ফেরত দেয়।"""
return abs(n) % 10
def last_digit_str(n):
"""একই উত্তর, string পদ্ধতি (তুলনার জন্য)।"""
return int(str(abs(n))[-1])
def last_k_digits(n, k):
"""বোনাস: শেষ k-টা digit একসাথে (% 10^k)।"""
return abs(n) % (10 ** k)
# --- ছোট test গুলো (সব pass করা উচিত) ---
assert last_digit(1234) == 4
assert last_digit(7) == 7
assert last_digit(0) == 0 # 0-এর last digit 0
assert last_digit(90) == 0 # শেষে শূন্য
assert last_digit(100) == 0
assert last_digit(-1234) == 4 # চিহ্ন বাদ
assert last_digit_str(1234) == 4 # দুই পদ্ধতি মেলে
assert last_digit_str(0) == 0
assert last_k_digits(1234, 2) == 34 # শেষ দুই digit
assert last_k_digits(5, 3) == 5 # digit কম হলে সংখ্যাটাই
print(last_digit(1234)) # 4
print(last_digit(90)) # 0
print(last_digit(-1234)) # 4
print("সব test pass!")
13. Line-by-line explanation¶
এটাই হৃদয়। abs(n) আগে চিহ্ন সরায় (যাতে negative-এ গোলমাল না হয় — নিচে common mistake দেখো), তারপর % 10 last digit তুলে আনে। পুরো কাজ এক লাইনে, এক ধাপে।
str(abs(n)) সংখ্যাকে string বানায়, [-1] তার শেষ অক্ষর নেয় (Python-এ -1 মানে "শেষ থেকে এক"), int() সেই অক্ষরকে আবার সংখ্যা বানায়। কাজ করে, কিন্তু ভেতরে string তৈরি হয়।
বোনাস — 10 ** k মানে 10-এর k power (যেমন 10 ** 2 = 100)। % 100 দেয় শেষ দুই digit, % 1000 শেষ তিন। section 10-এর generalize করা idea-টাই code-এ।
বাকি assert লাইনগুলো নিজেদের চেক করছে — উত্তর না মিললে program সেখানেই থেমে error দেবে। সব ঠিক থাকলে শেষে সব test pass! ছাপে।
14. Output walkthrough¶
চালালে যা ছাপবে:
প্রথম তিন লাইন তিনটা print(last_digit(...)) থেকে: 1234 → 4, 90 → 0 (শেষে শূন্য ঠিকঠাক ধরা পড়ল), -1234 → 4 (চিহ্ন বাদ)। তার আগের সব assert চুপচাপ pass করেছে (assert pass করলে কিছু ছাপে না)। সবশেষে সব test pass! — সব ঠিক আছে।
15. Time complexity¶
O(1) — constant time। n যত বড়ই হোক, একটাই % operation, একটাই তুলনা। সংখ্যার আকারের সাথে কাজ বাড়ে না।
(string version O(digit) — কারণ পুরো সংখ্যাকে string বানাতে সব digit পড়তে হয়; তাই last digit-এর জন্য সেটা একটু অপচয়।)
16. Space complexity¶
O(1) — % 10 পদ্ধতিতে কোনো বাড়তি list বা string লাগে না, শুধু গুটিকয় variable। (string version-এ O(digit), কারণ পুরো string মেমরিতে বানায়।)
17. Common mistakes¶
- negative-এ সরাসরি
n % 10— Python-এ-1234 % 10দেয়6(Python-এর modulo সবসময় 0..9-এর মধ্যে positive থাকে), অথচ আমরা চাই4। তাই আগেabs(n)নাও। (C++/Java-তে-1234 % 10দেয়-4— আরেক রকম গোলমাল।) তাই চিহ্ন আগে সামলাও। % 10আর// 10গুলিয়ে ফেলা —% 10last digit দেয়,// 10last digit ফেলে দেয়। last digit চাইলে%, peeling চাইলে//।% 2লিখে ফেলা — 001-এর অভ্যাসে; digit চাই বলে% 10লাগবে,% 2নয়।- শেষের শূন্য নিয়ে দ্বিধা —
90-এর last digit0, এটা ঠিক; "শূন্য কি digit?" — হ্যাঁ, অবশ্যই। - এই জন্য string বানানো — অভ্যাসবশত অনেকে
str(n)[-1]লেখে;% 10সরাসরি, দ্রুত, কম স্মৃতি।
18. Harder problems that inherit this idea¶
- LeetCode — Add Digits (https://leetcode.com/problems/add-digits/) — digit নিয়ে কাজ; এই last-digit তোলাই extraction-এর প্রথম ইট।
- 002 (Sum of Digits) আর 004 (Reverse Number) (এই repo) — দুটোতেই loop-এর ভেতরে এই
% 10বারবার ডাকা হয়; 008 সেই loop-এরই একক পদক্ষেপ। - Unit digit of a power (cyclicity) —
7^100-এর last digit বের করার classic interview pattern: last digit-রা চক্রাকারে ফেরে (7 → 9 → 3 → 1 → 7 ...), তাই% 10আর cycle length দিয়েই উত্তর, পুরো power হিসাব না করেই।
19. Pattern learned¶
Last digit via % 10। আর তার পেছনের বড় শিক্ষা: base-10-এ % 10^k দিয়ে শেষ kটা digit এক ধাপে কাটা যায়, কারণ 10-এর গুণিতক ভাগে মিলিয়ে যায়। এই "শেষটা এক ধাপে ছোঁয়া" চোখটাই 002-এর loop, 004-এর reverse, আর পরের cyclicity problem-এর ভিত্তি।
20. Final summary¶
ভবিষ্যতের আমাকে এক লাইনে: "last digit = abs(n) % 10 (চিহ্ন আগে সামলাও, নাহলে Python-এ negative-এ গোলমাল)। শেষ k digit চাইলে % 10^k। এটাই 001-এর % 2-এরই বড় ভাই, base 10-এ।"
আগের ধাপ → 001 — Even or Odd (যেখানে %-এর সাথে প্রথম পরিচয়)। সম্পর্কিত → 002 — Sum of Digits (এই % 10-কে loop-এ বসিয়ে)।
ফিরে দেখা: এই level-এর map → ../README.md · এই note-টা যে ছকে লেখা → ../../../templates/math-problem-note-template.md।
মনে রাখার নিয়ম (legal): সব নিজের ভাষায় লেখা; problem statement copy করা হয়নি; official link শুধু attribution-এর জন্য রাখা; "asked by Google/Amazon" এমন দাবি করা হয়নি — বরং "common interview pattern" হিসেবে লেখা।