এই পর্বে যা শিখবেন
- যোগ আর গুণের নিয়মকে সেটের উপপাদ্য হিসেবে লেখা আর induction দিয়ে প্রমাণ করা
- বিয়োগের নিয়ম আর complement দিয়ে “অন্তত একটি” ধরনের প্রশ্ন সমাধান, যেমন বাজারঘরের password নীতি
- Tree diagram দিয়ে এমন গণনা, যেখানে পরের পছন্দ আগের পছন্দের ওপর নির্ভর করে
- k-to-1 ফাংশন দিয়ে ভাগের নিয়মের প্রমাণ, গোল টেবিলের গণনা, আর কখন ভাগ করা যায় না
- Nested loop কতবার চলে তা গোনা, আর পরীক্ষার অঙ্কে overcounting ও undercounting-এর ভুল ধরা
১ · গোনার প্রশ্ন সবখানে — বাজারঘরের চারটি সমস্যা
কাল্পনিক অনলাইন দোকান বাজারঘরের প্রযুক্তি দল এক সকালে চারটি প্রশ্ন নিয়ে বসেছে। প্রথম প্রশ্ন: কুপন কোডে দুটি ইংরেজি বড় হাতের অক্ষর আর চারটি অঙ্ক থাকলে মোট কতগুলো আলাদা কুপন বানানো যায়, আর তা কি এক বছরের প্রচারণার জন্য যথেষ্ট? দ্বিতীয় প্রশ্ন: password-এর দৈর্ঘ্য ৬ থেকে ৮, আর তাতে অন্তত একটি অঙ্ক থাকতে হবে; এমন password কয়টি? তৃতীয় প্রশ্ন: বার্ষিক সভায় ৬ জন বিভাগীয় প্রধান একটি গোল টেবিলে বসবেন; কত রকম বসার ব্যবস্থা আসলে আলাদা? চতুর্থ প্রশ্ন: অর্ডার মেলানোর একটি প্রোগ্রামে দুটি nested loop আছে; n = 10,000 অর্ডারে ভেতরের লাইনটি কতবার চলবে?
চারটি প্রশ্নের মূলে একটিই কাজ: একটি সসীম সেটের উপাদান গোনা, তালিকা না বানিয়ে, কারণ উপাদান লাখ বা কোটির ঘরে। গণিতের যে শাখা এমন সেটের আকার বের করে, তার নাম combinatorics, বাংলায় সমাবেশবিদ্যা বা গণনাতত্ত্ব। এই মডিউলের সাতটি পর্ব তার মূল হাতিয়ার শেখাবে, আর পর্ব ৩৮ “বিচ্ছিন্ন সম্ভাবনা — sample space, event আর Laplace-এর সংজ্ঞা” থেকে সম্ভাবনা পুরোটাই এই গণনার ওপর দাঁড়াবে।
ভিত্তি আগেই তৈরি। পর্ব ১৪-এ দেখেছেন সসীম সেটের cardinality |A| মানে উপাদানের সংখ্যা, |A × B| = |A| · |B|, আর power set-এ 2nটি subset. পর্ব ১৫-এ প্রমাণ হয়েছে |A ∪ B| = |A| + |B| − |A ∩ B|, আর পর্ব ১৬-এ গোনা হয়েছে nmটি ফাংশন। এখানে এই তথ্যগুলোকে চারটি সাধারণ নিয়মে গুছিয়ে নেব: যোগ, গুণ, বিয়োগ আর ভাগ।
একটি দৈনন্দিন উপমা: চায়ের দোকানে ৩ রকম বিস্কুট আর ৪ রকম কেক। বিস্কুট অথবা কেক, একটা কিছু খেলে পছন্দ 3 + 4 = 7টি। একটা বিস্কুট এবং একটা কেক খেলে প্রতিটি বিস্কুটের সঙ্গে ৪টি কেক, মোট 3 × 4 = 12টি জোড়া। “অথবা” প্রায়ই যোগ আনে, “এবং তারপর” প্রায়ই গুণ; আসল শর্তগুলো পরের দুই অংশে।
যোগের নিয়ম বনাম গুণের নিয়ম: ডেলিভারি রাইডার বাছাই
ওপরে: যেকোনো একটি হাব থেকে একজন রাইডার (যোগ)। নিচে: প্রতিটি হাব থেকে একজন করে, একটি জোড়া (গুণ)।
ছবির ওপরের দুটি বাক্স একে অপরকে ছোঁয় না: কোনো রাইডার দুই হাবে নেই, তাই কাউকে দুবার গোনার ভয় নেই। নিচের অংশ হলো Cartesian product {D1, D2, D3} × {C1, C2, C3, C4}: প্রতিটি সারি একজন ঢাকার রাইডার, প্রতিটি কলাম একজন চট্টগ্রামের, আর প্রতিটি বিন্দু একটি জোড়া। ছক আয়তাকার বলেই গুণ খাটে: প্রতিটি সারিতে সমান সংখ্যক বিন্দু।
২ · যোগের নিয়ম — “অথবা” মানে আলাদা আলাদা ভাগ
প্রথমে কাজের ভাষায় নিয়মটি বলি, তারপর সেটের ভাষায় নিখুঁত করি। একটি কাজ দুই ভাবে করা যায়: প্রথম ভাবে n1 উপায়ে, দ্বিতীয় ভাবে n2 উপায়ে, আর কোনো উপায় দুই দলেই পড়ে না। তাহলে কাজটি n1 + n2 উপায়ে করা যায়। এটিই যোগের নিয়ম (sum rule). “কোনো উপায় দুই দলেই পড়ে না” শর্তটি নিয়মের প্রাণ; এটি বাদ দিলে নিয়মটি মিথ্যা।
A1, A2, …, Am সসীম সেট, আর এরা জোড়ায় জোড়ায় বিচ্ছিন্ন (pairwise disjoint), অর্থাৎ i ≠ j হলে Ai ∩ Aj = ∅. তাহলে
|A1 ∪ A2 ∪ ⋯ ∪ Am| = |A1| + |A2| + ⋯ + |Am|
এখানে ∪ হলো union (যেকোনো একটিতে আছে এমন সব উপাদান), আর ∩ হলো intersection (দুটিতেই আছে এমন উপাদান)। প্রমাণ m-এর ওপর পর্ব ১০-এর mathematical induction দিয়ে, আর ভিত্তি হিসেবে পর্ব ১৫-এর দুই সেটের সূত্র।
প্রমাণ: P(m) বিবৃতিটি হলো “যেকোনো m-টি জোড়ায় জোড়ায় বিচ্ছিন্ন সসীম সেটের জন্য সূত্রটি সত্য”।
- ভিত্তি, m = 1: |A1| = |A1|, কিছু প্রমাণের নেই। — সরাসরি
- m = 2: পর্ব ১৫-এর উপপাদ্য ৩.১ অনুযায়ী |A1 ∪ A2| = |A1| + |A2| − |A1 ∩ A2|, আর বিচ্ছিন্ন বলে |A1 ∩ A2| = |∅| = 0. — দুই সেটের inclusion–exclusion
- ধাপ: ধরি P(m) সত্য, আর A1, …, Am+1 জোড়ায় জোড়ায় বিচ্ছিন্ন। লিখি B = A1 ∪ ⋯ ∪ Am. — inductive hypothesis
- B ∩ Am+1 = (A1 ∩ Am+1) ∪ ⋯ ∪ (Am ∩ Am+1) = ∅ ∪ ⋯ ∪ ∅ = ∅. — distributive law, পর্ব ১৫
- তাই m = 2-এর ক্ষেত্র থেকে |B ∪ Am+1| = |B| + |Am+1|, আর P(m) থেকে |B| = |A1| + ⋯ + |Am|. দুটি মিলিয়ে P(m + 1). ∎ — বসানো
কাজের রূপে “প্রথম ভাবে করার সব উপায়” হলো A1, “দ্বিতীয় ভাবে” A2, আর কোনো উপায় দুই দলে না পড়া মানে A1 ∩ A2 = ∅.
কয়েকটি উদাহরণ
- রাইডার বাছাই: জরুরি একটি পার্সেল ঢাকার ৩ জন অথবা চট্টগ্রামের ৪ জন রাইডারের যেকোনো একজন নিতে পারেন। কেউ দুই হাবে নেই, তাই 3 + 4 = 7.
- বিভিন্ন দৈর্ঘ্যের কোড: একটি string একসঙ্গে দুই দৈর্ঘ্যের হতে পারে না, তাই দৈর্ঘ্য অনুযায়ী ভাগ সবসময় বিচ্ছিন্ন। password গোনায় ঠিক এটিই করব।
সাবধান: “অথবা” শব্দ দেখলেই যোগ করবেন না। “৮ bit-এর যে string 1 দিয়ে শুরু অথবা 00 দিয়ে শেষ” প্রশ্নে দুই দলে মিল আছে: 10000000 দুটোতেই পড়ে। তখন সরল যোগ সেই string-গুলো দুবার গোনে। এই ভুলের নাম overcounting, আর তার প্রতিকার §৪-এর বিয়োগের নিয়ম।
৩ · গুণের নিয়ম — “এবং তারপর” মানে ধাপে ধাপে বাছাই
বাজারঘরের কুপন কোডের গঠন LLDDDD: প্রথম দুটি ঘরে A থেকে Z-এর একটি অক্ষর, পরের চারটিতে 0 থেকে 9-এর একটি অঙ্ক। একটি কোড বানানো মানে ছয়টি ধাপে পরপর ছয়টি বাছাই। প্রথম ঘরের ২৬টি পছন্দের প্রতিটির সঙ্গে দ্বিতীয় ঘরের ২৬টি মেলে, তাই প্রথম দুই ঘরে 26 · 26 = 676টি জোড়া; প্রতিটির সঙ্গে আবার অঙ্কের ঘরগুলো। সব মিলিয়ে 262 · 104 = 6,760,000টি কুপন।
A1, …, Am সসীম সেট হলে
|A1 × A2 × ⋯ × Am| = |A1| · |A2| ⋯ |Am|
এখানে A1 × ⋯ × Am হলো সব ক্রমযুক্ত m-tuple (a1, …, am)-এর সেট, যেখানে প্রতিটি ai ∈ Ai.
প্রমাণ: m = 2-এর ক্ষেত্রটি পর্ব ১৪-এর উপপাদ্য ৫.২. এখানে সেটিকে যোগের নিয়ম থেকে আরেকবার দেখি, কারণ এই যুক্তিটিই গুণের নিয়মের আসল ব্যাখ্যা।
- A × B = ⋃a ∈ A ({a} × B): প্রতিটি জোড়া (a, b) ঠিক সেই অংশে পড়ে, যার প্রথম উপাদান a. — সংজ্ঞা
- a ≠ a′ হলে {a} × B আর {a′} × B বিচ্ছিন্ন, কারণ তাদের জোড়াগুলোর প্রথম উপাদান আলাদা। — ordered pair-এর সমতা
- প্রতিটি {a} × B-তে |B|টি উপাদান, কারণ b ↦ (a, b) একটি bijection. — পর্ব ১৬
- যোগের নিয়মে |A × B| = |B| + |B| + ⋯ + |B| (|A| বার) = |A| · |B|. — উপপাদ্য ২.১
- সাধারণ m: m-এর ওপর induction. (a1, …, am+1) ↦ ((a1, …, am), am+1) একটি bijection A1 × ⋯ × Am+1 → (A1 × ⋯ × Am) × Am+1, তাই আকার সমান। m = 2-এর ক্ষেত্র আর inductive hypothesis মিলিয়ে |A1| ⋯ |Am| · |Am+1|. ∎ — induction
ধাপ ৪ দেখায় গুণ আসলে সমান মাপের সারির বারবার যোগ। এ থেকেই কাজের ভাষার নিয়মটি আসে, যা সেটের রূপের চেয়ে একটু বেশি শক্তিশালী।
একটি কাজ পরপর m-টি ধাপে হয়। আগের ধাপগুলোতে যা-ই বাছা হোক, ধাপ i-তে পছন্দের সংখ্যা সবসময় ni, আর আলাদা বাছাইয়ের ক্রম আলাদা ফল দেয়। তাহলে কাজটি n1 · n2 ⋯ nm উপায়ে করা যায়।
সূক্ষ্ম বিষয়টি খেয়াল করুন: পছন্দের সেট আগের বাছাইয়ের ওপর নির্ভর করতে পারে, কিন্তু পছন্দের সংখ্যা নয়। কুপনের দুটি অক্ষর আলাদা হতে হবে, এমন নিয়ম হলে প্রথম অক্ষরে ২৬টি পছন্দ, দ্বিতীয়টিতে ২৫টি; কোন ২৫টি, তা প্রথম অক্ষরের ওপর নির্ভর করে, কিন্তু সংখ্যা সবসময় ২৫. তাই 26 · 25 · 104 = 6,500,000. ১৫ জনের ক্রিকেট স্কোয়াড থেকে অধিনায়ক আর সহ-অধিনায়ক বাছাইও তাই: 15 · 14 = 210. কিন্তু সংখ্যাও বদলালে, যেমন “দ্বিতীয় অক্ষর বর্ণমালায় প্রথমটির পরে”, সরল গুণ চলে না; তখন প্রথম অক্ষর অনুযায়ী ভাগ করে যোগ (25 + 24 + ⋯ + 0), অথবা §৫-এর tree diagram.
পুরোনো ফলাফল, নতুন চোখে
আগের মডিউলের তিনটি বিখ্যাত গণনা আসলে একই গুণের নিয়ম। প্রতিটির পেছনে একটি “প্রতিটি অবস্থানে একটি বাছাই” আছে।
| কী গুনছি | ধাপগুলো | উত্তর |
|---|---|---|
| k দৈর্ঘ্যের string, n অক্ষরের alphabet থেকে | প্রতিটি অবস্থানে n-টি অক্ষরের একটি | nk |
| |A| = m থেকে |B| = n-এ ফাংশন (পর্ব ১৬) | প্রতিটি a ∈ A-এর জন্য f(a) বাছাই | nm |
| n উপাদানের সেটের subset (পর্ব ১৪) | প্রতিটি উপাদান “ভেতরে” অথবা “বাইরে” | 2n |
| n দৈর্ঘ্যের bit string | প্রতিটি অবস্থানে 0 বা 1 | 2n |
| m ≤ n হলে one-to-one ফাংশন | প্রতিবার আগের মানগুলো বাদ | n(n − 1)⋯(n − m + 1) |
শেষ সারিটি পর্ব ৩৩ “Permutation আর combination”-এর আগাম স্বাদ। subset আর bit string-এর উত্তর একই, কারণ দুটির মধ্যে একটি bijection আছে; “bijection থাকলে আকার সমান” নীতিটি পর্ব ৩৭ “গণনার কৌশল — lattice path, bijection আর double counting”-এ নিজস্ব নাম পাবে।
নিচের ব্লক একটি খেলনা কুপন-নিয়মে (অক্ষর A, B, C আর অঙ্ক 0, 1) itertools.product দিয়ে সব কোড বানিয়ে গোনে, তারপর আসল নিয়মে সূত্র দিয়ে হিসাব করে। product ঠিক Cartesian product বানায়, অর্থাৎ উপপাদ্য ৩.১-এর যন্ত্রচালিত রূপ। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।
from itertools import product
from string import ascii_uppercase, digits
# toy version: letters from {A,B,C}, digits from {0,1}: LLDD
toy = ["".join(t) for t in product("ABC", "ABC", "01", "01")]
print("toy codes:", len(toy), "formula 3*3*2*2 =", 3 * 3 * 2 * 2)
print("first five:", toy[:5])
# product rule: |A1 x A2 x A3 x A4 x A5 x A6| for LLDDDD
L, D = len(ascii_uppercase), len(digits)
print("real LLDDDD codes:", L**2 * D**4)
# letters must differ: still the same number of choices at each stage
pairs = sum(1 for a, b in product(ascii_uppercase, repeat=2) if a != b)
print("letters different:", pairs * D**4, "= 26*25*10^4 =", 26 * 25 * 10**4)
# sum rule: a code is 5 characters OR 6 characters (disjoint sets)
five = L * D**4 # LDDDD
six = L**2 * D**4 # LLDDDD
print("5-char or 6-char codes:", five + six)
# functions and subsets are the product rule again
funcs = list(product(range(4), repeat=3)) # f(a1), f(a2), f(a3) from 4 values
subsets = list(product((0, 1), repeat=5)) # in or out, for each of 5 elements
print("functions 3 -> 4:", len(funcs), "| subsets of a 5-set:", len(subsets))আসল আউটপুট (ব্রাউজারের Python):
toy codes: 36 formula 3*3*2*2 = 36
first five: ['AA00', 'AA01', 'AA10', 'AA11', 'AB00']
real LLDDDD codes: 6760000
letters different: 6500000 = 26*25*10^4 = 6500000
5-char or 6-char codes: 7020000
functions 3 -> 4: 64 | subsets of a 5-set: 32
খেলনা নিয়মে যন্ত্র ৩৬টি কোড বানিয়েছে, সূত্রও 36 বলে। প্রথম পাঁচটি কোডের ক্রম দেখুন: শেষের ঘর সবচেয়ে দ্রুত বদলায়, ঠিক গাড়ির মিটারের মতো; product এই “অভিধান ক্রমে” tuple দেয়। আসল নিয়মে 6,760,000টি কুপন, আর অক্ষর দুটি আলাদা রাখলে 6,500,000; brute force-এ গোনা 650টি আলাদা অক্ষর-জোড়া 26 · 25-এর সঙ্গে মিলেছে। ৫ বা ৬ অক্ষরের কোড বিচ্ছিন্ন দুই দল, তাই 260,000 + 6,760,000 = 7,020,000. শেষ লাইনে ফাংশন 43 = 64 আর subset 25 = 32, দুটিই একই product দিয়ে।
৪ · বিয়োগের নিয়ম আর complement — বাজারঘরের password নীতি
দুই দলে মিল থাকলে যোগের নিয়ম মিলের অংশটি দুবার গোনে। সংশোধন সহজ: একবার বাদ দিন। এটিই বিয়োগের নিয়ম (subtraction rule), যাকে দুই সেটের inclusion–exclusion-ও বলে।
A আর B সসীম সেট হলে |A ∪ B| = |A| + |B| − |A ∩ B|. কাজের ভাষায়: একটি কাজ n1 উপায়ে অথবা n2 উপায়ে করা যায়, আর এর মধ্যে n12টি উপায় দুই দলেই আছে, তাহলে মোট n1 + n2 − n12.
প্রমাণ পর্ব ১৫-এর উপপাদ্য ৩.১-এ আছে (A ∪ B-কে তিনটি বিচ্ছিন্ন অংশ A ∖ B, A ∩ B আর B ∖ A-তে ভেঙে যোগের নিয়ম)। তিন বা তার বেশি সেটের সাধারণ সূত্র, যেখানে চিহ্ন পালাক্রমে বদলায়, পর্ব ৪৯ “Inclusion–exclusion আর derangement”-এর বিষয়। এখানে একটি উদাহরণ: ৮ bit-এর কতগুলো string 1 দিয়ে শুরু অথবা 00 দিয়ে শেষ? A = “1 দিয়ে শুরু”, বাকি ৭টি ঘর মুক্ত, |A| = 27 = 128. B = “00 দিয়ে শেষ”, বাকি ৬টি ঘর মুক্ত, |B| = 26 = 64. A ∩ B-তে প্রথম ঘর আর শেষ দুই ঘর স্থির, |A ∩ B| = 25 = 32. উত্তর 128 + 64 − 32 = 160.
Complement: উল্টো দিক থেকে গোনা
বিয়োগের নিয়মের সবচেয়ে কাজের রূপটি হলো complement rule. মহাবিশ্ব U-এর মধ্যে A-এর complement Ā = U ∖ A.
U সসীম আর A ⊆ U হলে |A| = |U| − |Ā|.
প্রমাণ:
- U = A ∪ Ā, কারণ U-এর প্রতিটি উপাদান হয় A-তে, নয় A-এর বাইরে। — complement-এর সংজ্ঞা
- A ∩ Ā = ∅, কারণ একটি উপাদান একসঙ্গে A-তে আর A-এর বাইরে থাকতে পারে না। — সংজ্ঞা
- যোগের নিয়মে |U| = |A| + |Ā|, তাই |A| = |U| − |Ā|. ∎ — উপপাদ্য ২.১
এর কাজ কোথায়? যখন A-এর বর্ণনায় “অন্তত একটি” থাকে। “অন্তত একটি অঙ্ক” মানে একটি, দুটি, তিনটি, … অঙ্ক, আর প্রতিটিতে কোন ঘরে, তা নিয়ে উপ-ক্ষেত্র। কিন্তু complement “একটিও অঙ্ক নেই” মানে শুধু একটি সহজ শর্ত: প্রতিটি ঘরে একটি অক্ষর।
এবার বাজারঘরের নিয়ম। password-এ শুধু ছোট হাতের ইংরেজি অক্ষর (a–z, ২৬টি) আর অঙ্ক (0–9, ১০টি) চলে, মোট ৩৬টি চিহ্ন। দৈর্ঘ্য ৬, ৭ বা ৮, আর অন্তত একটি অঙ্ক থাকতে হবে। Pn দিয়ে n দৈর্ঘ্যের বৈধ password-এর সেট বোঝাই। দৈর্ঘ্য আলাদা হলে password আলাদা, তাই প্রথমে যোগের নিয়ম, তারপর প্রতিটি দৈর্ঘ্যে complement.
1P = P₆ ∪ P₇ ∪ P₈2|U₆| = 36⁶3|P₆| = 36⁶ − 26⁶4|P₇| = 36⁷ − 26⁷5|P₈| = 36⁸ − 26⁸6|P| = |P₆| + |P₇| + |P₈|
| দৈর্ঘ্য n | |
| মোট 36ⁿ | |
| অঙ্কহীন 26ⁿ | |
| |Pₙ| | |
| মোট যোগফল |
- যোগের নিয়মে ভাগ। একটি password-এর দৈর্ঘ্য ঠিক একটি, তাই P6, P7, P8 বিচ্ছিন্ন, আর |P| = |P6| + |P7| + |P8|. এখন প্রতিটি দৈর্ঘ্য আলাদা করে গুনব।
- মহাবিশ্ব। ৬ দৈর্ঘ্যের সব string, অঙ্ক থাকুক বা না থাকুক: প্রতিটি ঘরে ৩৬টি চিহ্ন, গুণের নিয়মে 366 = 2,176,782,336.
- Complement বাদ। “অন্তত একটি অঙ্ক”-এর complement “শুধু অক্ষর”: 266 = 308,915,776. তাই |P6| = 2,176,782,336 − 308,915,776 = 1,867,866,560.
- দৈর্ঘ্য ৭. একই যুক্তি: 367 − 267 = 78,364,164,096 − 8,031,810,176 = 70,332,353,920. চলতি যোগফল 72,200,220,480.
- দৈর্ঘ্য ৮. 368 − 268 = 2,821,109,907,456 − 208,827,064,576 = 2,612,282,842,880. বড় দৈর্ঘ্যই প্রায় পুরো যোগফল দখল করে।
- উত্তর। |P| = 1,867,866,560 + 70,332,353,920 + 2,612,282,842,880 = 2,684,483,063,360, প্রায় 2.68 × 1012টি password. দুটি নিয়ম পরপর: বাইরে যোগ, ভেতরে complement.
এত বড় সংখ্যা brute force করা যায় না, কিন্তু একই পদ্ধতি ছোট alphabet-এ মেলানো যায়। নিচের ব্লক a, b, c আর 0, 1 নিয়ে ২ থেকে ৪ দৈর্ঘ্যের সব string পরীক্ষা করে, আর একটি জনপ্রিয় ভুল পদ্ধতিও চালায়: “আগে অঙ্কের জন্য একটি ঘর বাছি (n উপায়), সেখানে একটি অঙ্ক বসাই (২ উপায়), বাকি ঘর যা খুশি (5n−1)”.
from itertools import product
letters, digs = "abc", "01" # toy alphabet: 3 letters + 2 digits
alpha = letters + digs
def has_digit(w):
return any(ch in digs for ch in w)
total = 0
for n in range(2, 5): # lengths 2, 3, 4 (sum rule over lengths)
brute = sum(1 for w in product(alpha, repeat=n) if has_digit(w))
formula = len(alpha)**n - len(letters)**n # all minus 'no digit'
wrong = n * len(digs) * len(alpha)**(n - 1) # 'pick the digit spot' method
print(f"n={n}: brute {brute}, complement {formula}, wrong {wrong}")
total += brute
print("toy policy total:", total)
# the Bazarghar rule: a-z and 0-9, length 6..8, at least one digit
real = sum(36**n - 26**n for n in (6, 7, 8))
print("real policy:", real, f"(about {real:.2e})")
# why 'wrong' overcounts: a string with two digits is counted twice
w = ("0", "1")
spots = [i for i, ch in enumerate(w) if ch in digs]
print(w, "is counted", len(spots), "times by the wrong method")আসল আউটপুট (ব্রাউজারের Python):
n=2: brute 16, complement 16, wrong 20
n=3: brute 98, complement 98, wrong 150
n=4: brute 544, complement 544, wrong 1000
toy policy total: 658
real policy: 2684483063360 (about 2.68e+12)
('0', '1') is counted 2 times by the wrong method
প্রতিটি দৈর্ঘ্যে brute force আর complement সূত্র হুবহু মিলেছে (16, 98, 544), আর খেলনা নীতির মোট 658. আসল নীতির সংখ্যা stepper-এর 2,684,483,063,360-এর সঙ্গে মেলে। “ঘর বেছে অঙ্ক বসানো” পদ্ধতি প্রতিবার বেশি দিয়েছে: n = 2-এ 20, যেখানে আসল 16. কারণ শেষ লাইনে: “01” string-টি দুবার গোনা হয়, একবার “প্রথম ঘরে অঙ্ক” হিসেবে, একবার “দ্বিতীয় ঘরে অঙ্ক” হিসেবে। দুই অঙ্কের ৪টি string (00, 01, 10, 11) দুবার করে গোনায় 16 + 4 = 20. একাধিক অঙ্ক থাকলে বাছাইয়ের “পরিচয়” হারিয়ে যায়, এটিই overcounting-এর ধ্রুপদি রূপ।
এই সংখ্যা নিরাপত্তার পূর্ণ মাপ নয়, কারণ মানুষ সব password সমান সম্ভাবনায় বাছেন না। ব্যবহারিক দিক Cybersecurity কোর্সের পর্ব ১৫ আর পর্ব ১৩-এ।
৫ · Tree diagram — যখন পরের পছন্দ আগের পছন্দের ওপর নির্ভর করে
গুণের নিয়মের শর্ত ছিল প্রতিটি ধাপে পছন্দের সংখ্যা স্থির। শর্তটি না খাটলে একটি নির্ভরযোগ্য বিকল্প হলো tree diagram: শিকড় থেকে শুরু করে প্রতিটি সম্ভাব্য পছন্দের জন্য একটি শাখা আঁকুন, আর প্রতিটি শাখার শেষ থেকে পরের ধাপের শাখা। শিকড় থেকে একটি পাতা (leaf) পর্যন্ত প্রতিটি পথ ঠিক একটি সম্পূর্ণ ফল, তাই উত্তর হলো পাতার সংখ্যা। অবৈধ শাখা শুরুতেই কেটে ফেলা যায়।
একটি উদাহরণ নিই। বাজারঘরের একটি গুদামের সেন্সর প্রতি ঘণ্টায় একটি bit পাঠায়: 0 মানে স্বাভাবিক, 1 মানে সতর্কতা। নিয়ম হলো পরপর দুটি সতর্কতা (অর্থাৎ “11”) এলে লাইন বন্ধ হয়। ৪ ঘণ্টায় লাইন চালু থাকে, এমন কতগুলো bit string সম্ভব? এখানে পছন্দের সংখ্যা স্থির নয়: শেষ bit 0 হলে পরেরটি 0 বা 1 (২টি পছন্দ), শেষ bit 1 হলে পরেরটি শুধু 0 (১টি)।
- শিকড়। এখনো কোনো bit নেই। প্রথম ঘণ্টায় 0 বা 1, দুটিই চলে, কারণ আগে কোনো 1 নেই।
- স্তর ১: 2টি। “0” আর “1”. এ পর্যন্ত গুণের নিয়মের মতোই, প্রতিটি শাখায় ২টি পছন্দ ছিল।
- স্তর ২: 3টি। “0”-এর পরে 0 বা 1: 00, 01. কিন্তু “1”-এর পরে শুধু 0: 10. লাল দাগ “11” শাখা, যা কাটা। এখানেই পছন্দের সংখ্যা অসমান হলো, তাই সরল গুণ আর চলে না।
- স্তর ৩: 5টি। 000, 001 (00 থেকে), 010 (01 থেকে, 011 কাটা), 100, 101 (10 থেকে)। যে শাখা 1-এ শেষ, তার একটিই সন্তান।
- স্তর ৪: 8টি। 0000, 0001, 0010, 0100, 0101, 1000, 1001, 1010. কাটা গেছে 0011 আর 1011, কারণ দুটিই 1-এ শেষ হওয়া শাখার পরে আরেকটি 1.
- পাতা গোনা। শিকড় থেকে প্রতিটি পাতার পথ একটি বৈধ string, তাই উত্তর 8 (মোট 24 = 16-এর অর্ধেক)। স্তরের সংখ্যা 2, 3, 5, 8: প্রতিটি আগের দুটির যোগফল, Fibonacci-র ধারা, যার কারণ নিচে।
2, 3, 5, 8 কেন Fibonacci? n দৈর্ঘ্যের বৈধ string-এর সংখ্যা an ধরুন, আর শেষ bit অনুযায়ী বৈধ string-গুলোকে দুই বিচ্ছিন্ন দলে ভাগ করুন। শেষ bit 0 হলে সামনের অংশ যেকোনো বৈধ (n − 1) দৈর্ঘ্যের string: an−1টি। শেষ bit 1 হলে তার আগের bit অবশ্যই 0, অর্থাৎ শেষ দুই bit “01”, আর সামনের অংশ যেকোনো বৈধ (n − 2) দৈর্ঘ্যের string: an−2টি। যোগের নিয়মে an = an−1 + an−2, যেখানে a1 = 2, a2 = 3. এই কৌশলের পূর্ণ রূপ পর্ব ৪৪ “Recurrence দিয়ে মডেল — Fibonacci, Hanoi আর bit string”-এ; Fibonacci-র ধর্মগুলো পর্ব ১২-এ দেখেছেন।
Tree diagram ছোট সমস্যায় অসাধারণ, কারণ এটি কোনো শর্ত ভুলে যেতে দেয় না। ক্রিকেটের “best of three” সিরিজের কথা ভাবুন: যে দল আগে দুটি ম্যাচ জেতে, সিরিজ তার। দুই দল A আর B হলে সিরিজ কতভাবে শেষ হতে পারে? Tree আঁকলে পাতাগুলো AA, ABA, ABB, BAA, BAB, BB: মোট ৬টি। পথের দৈর্ঘ্যও আলাদা (২ বা ৩ ম্যাচ), যা সরল গুণে ধরা যায় না। অসুবিধা হলো tree দ্রুত বড় হয়; তখন তার গঠন থেকে recurrence বের করাই পথ।
৬ · ভাগের নিয়ম — k-to-1 ফাংশন আর গোল টেবিল
বার্ষিক সভার প্রশ্নে ফিরি। ৬ জন বিভাগীয় প্রধান (A থেকে F) একটি গোল টেবিলে বসবেন। দুটি ব্যবস্থাকে একই ধরা হয়, যদি প্রত্যেকের বাঁ পাশের আর ডান পাশের প্রতিবেশী একই থাকেন; অর্থাৎ সবাই মিলে এক চেয়ার ঘুরে বসলে নতুন ব্যবস্থা হয় না। চেয়ারে কোনো নম্বর নেই, শুধু কে কার পাশে, সেটিই গুরুত্বপূর্ণ।
সরাসরি গোনা কঠিন, কিন্তু একটি সহজ জিনিস গোনা সহজ: ৬ জনকে একটি সরলরেখায় সাজানো, 6! = 720 উপায়ে (factorial, গুণের নিয়মে 6 · 5 · 4 · 3 · 2 · 1). এখন প্রতিটি সারি থেকে একটি টেবিল-ব্যবস্থা পাওয়া যায়: সারির প্রথম জন একটি চেয়ারে, বাকিরা ঘড়ির কাঁটার দিকে পরপর। কিন্তু একই টেবিল একাধিক সারি থেকে আসে: যেখান থেকেই পড়া শুরু করুন, একই বৃত্ত। গোনার ভাষায় আমরা প্রতিটি টেবিল কয়েকবার গুনেছি। কতবার, সেটি জানা থাকলে ভাগ করলেই চলে।
একটি ফাংশন f: A → B হলো k-to-1, যদি B-এর প্রতিটি উপাদান b-এর জন্য ঠিক k-টি a ∈ A থাকে, যাতে f(a) = b. অর্থাৎ প্রতিটি b-এর preimage f−1(b)-এর আকার ঠিক k. (k = 1 হলে এটি bijection.)
A সসীম, k ≥ 1, আর f: A → B একটি k-to-1 ফাংশন হলে |B| = |A| / k.
প্রমাণ:
- A = ⋃b ∈ B f−1(b), কারণ প্রতিটি a ঠিক একটি b = f(a)-এর preimage-এ পড়ে। — ফাংশনের সংজ্ঞা
- b ≠ b′ হলে f−1(b) ∩ f−1(b′) = ∅, কারণ একটি a-এর দুটি আলাদা ছবি থাকতে পারে না। — ফাংশন well-defined
- প্রতিটি f−1(b)-এর আকার k, আর k ≥ 1 বলে প্রতিটি b-এর অন্তত একটি preimage আছে, তাই B-ও সসীম। — k-to-1-এর সংজ্ঞা
- যোগের নিয়মে |A| = ∑b ∈ B |f−1(b)| = k · |B|, তাই |B| = |A| / k. ∎ — উপপাদ্য ২.১
এটি গুণের নিয়মের প্রমাণ উল্টো দিক থেকে পড়া। ভাগগুলো (preimage) একটি equivalence relation-এর শ্রেণি: “দুটি সারি একই টেবিল দেয়”. নিয়মটি খাটে ঠিক তখন, যখন প্রতিটি শ্রেণির আকার সমান।
1A = সারিতে সাজানো, |A| = 6!2f(সারি) = টেবিল-ব্যবস্থা3ABCDEF, BCDEFA, …, FABCDE4প্রতিটি টেবিলে ঠিক 6টি সারি5|B| = 720 / 6 = 1206যাচাই: A স্থির, বাকি 5! = 120
| সারির সংখ্যা | |
| একটি টেবিলের সারি | |
| টেবিলের সংখ্যা |
- সহজ সেট। A = ৬ জনকে একটি সরলরেখায় সাজানোর সব উপায়। প্রথম ঘরে ৬ জন, তারপর ৫, …, শেষে ১: গুণের নিয়মে 6! = 720.
- ফাংশন। f একটি সারিকে টেবিলে বসায়: প্রথম জন যেকোনো একটি চেয়ারে, বাকিরা ঘড়ির কাঁটার দিকে পরপর। B = সব আলাদা টেবিল-ব্যবস্থা। f onto, কারণ যেকোনো টেবিলকে কোনো এক জায়গা থেকে পড়লে একটি সারি মেলে।
- কোন সারি একই টেবিল দেয়? ABCDEF টেবিলটি ঘড়ির কাঁটার দিকে যেকোনো জন থেকে পড়া যায়: ABCDEF, BCDEFA, CDEFAB, DEFABC, EFABCD, FABCDE. ছয়টিই একই প্রতিবেশী-সম্পর্ক।
- ঠিক 6টি কেন? শুরুর জন ৬ জনের যেকোনো একজন, আর সবাই আলাদা মানুষ বলে ছয়টি ঘোরানো রূপ পরস্পর আলাদা সারি। তাই প্রতিটি টেবিলের preimage-এ ঠিক 6টি সারি: f একটি 6-to-1 ফাংশন।
- ভাগ। উপপাদ্য ৬.২ অনুযায়ী টেবিলের সংখ্যা 720 / 6 = 120. সাধারণভাবে n জন (n ≥ 1) গোল টেবিলে n!/n = (n − 1)! উপায়ে বসেন।
- দ্বিতীয় পথে যাচাই। A-কে একটি নির্দিষ্ট চেয়ারে বসিয়ে দিলে ঘোরানোর স্বাধীনতা চলে যায়; বাকি ৫ জনকে তাঁর থেকে ঘড়ির কাঁটার দিকে 5! = 120 উপায়ে সাজানো যায়। দুই পথে একই উত্তর, গণনায় এটিই সবচেয়ে ভরসার যাচাই।
গোল টেবিলে এমন বসানোকে বলে circular permutation; পর্ব ৩৩-এ এটি permutation-এর একটি রূপ হিসেবে আবার আসবে। আয়নার প্রতিচ্ছবিও একই ধরলে (যেমন উল্টে দেওয়া যায় এমন মালা) n ≥ 3-এ শ্রেণি দ্বিগুণ বড়, উত্তর (n − 1)!/2; ৬ জনে 60. নিচের ব্লক n = 3 থেকে 7 পর্যন্ত সব সারিকে এমনভাবে ঘোরায় যাতে ব্যক্তি 0 সামনে আসে, সেই রূপ দিয়ে টেবিল আলাদা করে, আর প্রতিটি শ্রেণির আকার ছাপে।
from itertools import permutations
from math import factorial
def seat_class(p): # rotate so that person 0 comes first
i = p.index(0)
return p[i:] + p[:i]
for n in range(3, 8):
classes = {}
for p in permutations(range(n)): # all n! straight-line orders
classes.setdefault(seat_class(p), []).append(p)
sizes = {len(v) for v in classes.values()}
print(f"n={n}: line orders {factorial(n):4}, tables {len(classes):3}, "
f"class sizes {sizes}, (n-1)! = {factorial(n - 1)}")
# when the division rule FAILS: 2 red + 2 blue beads on a ring
lines = set(permutations("RRBB"))
ring = {}
for w in lines:
key = min("".join(w[i:] + w[:i]) for i in range(4))
ring.setdefault(key, []).append("".join(w))
print("lines:", len(lines), "-> 6/4 =", len(lines) / 4)
for k, v in sorted(ring.items()):
print(" ring", k, "has", len(v), "line forms:", sorted(v))আসল আউটপুট (ব্রাউজারের Python):
n=3: line orders 6, tables 2, class sizes {3}, (n-1)! = 2
n=4: line orders 24, tables 6, class sizes {4}, (n-1)! = 6
n=5: line orders 120, tables 24, class sizes {5}, (n-1)! = 24
n=6: line orders 720, tables 120, class sizes {6}, (n-1)! = 120
n=7: line orders 5040, tables 720, class sizes {7}, (n-1)! = 720
lines: 6 -> 6/4 = 1.5
ring BBRR has 4 line forms: ['BBRR', 'BRRB', 'RBBR', 'RRBB']
ring BRBR has 2 line forms: ['BRBR', 'RBRB']
প্রথম পাঁচ লাইনে প্রতিটি n-এ টেবিলের সংখ্যা (n − 1)!-এর সঙ্গে মিলেছে, আর class sizes সবসময় একটিমাত্র মান {n}: প্রতিটি শ্রেণিতে ঠিক n-টি সারি, তাই ভাগের নিয়ম বৈধ। n = 6-এ 720টি সারি থেকে 120টি টেবিল, stepper-এর উত্তর। শেষ তিন লাইন সতর্কবাণী। ২টি লাল (R) আর ২টি নীল (B) পুঁতি একটি আংটিতে: সারিতে সাজানো যায় ৬ উপায়ে, আর ঘোরানো যায় ৪ রকম। “6/4” ভাগ করলে 1.5, যা কোনো গণনার উত্তর হতে পারে না। কারণ শ্রেণিগুলো সমান নয়: BBRR-এর শ্রেণিতে ৪টি রূপ, কিন্তু BRBR ঘোরালে ২ ধাপেই নিজের কাছে ফিরে আসে, তাই তার শ্রেণিতে মাত্র ২টি। আসল উত্তর ২টি আংটি। মানুষেরা সবাই আলাদা বলে গোল টেবিলে এই সমস্যা হয়নি; একই রঙের পুঁতিতে হয়।
সমান নয় এমন শ্রেণির সাধারণ সমাধান Burnside-এর lemma, যা ভাবনার প্রশ্ন ৩-এ সংক্ষেপে আর পর্ব ৫১ “Symmetry দিয়ে গণনা — Burnside-এর lemma আর Pólya”-তে বিস্তারিত আছে।
৭ · অ্যালগরিদমে গণনা — nested loop কতবার চলে
একটি nested loop মানে একটি loop-এর ভেতরে আরেকটি। ভেতরের লাইন কতবার চলে, তা গোনা মানে যে সব (i, j) জোড়ায় লাইনটি চলে, তাদের সেটের আকার বের করা। চারটি নিয়মই এখানে কাজে লাগে।
- গুণ:
for i in range(n): for j in range(n)— জোড়ার সেট {0, …, n − 1} × {0, …, n − 1}, আকার n2. - যোগ: পরপর দুটি আলাদা loop, বা
if/else-এর দুই শাখা, বিচ্ছিন্ন ঘটনা; ধাপের সংখ্যা যোগ হয়। - ভাগ:
for j in range(i + 1, n)শুধু i < j জোড়া নেয়। i ≠ j এমন ক্রমযুক্ত জোড়া গুণের নিয়মে n(n − 1)টি। প্রতিটি অক্রমিক জোড়া {i, j} ঠিক দুটি ক্রমযুক্ত জোড়া দেয় ((i, j) আর (j, i)), আর তার ঠিক একটিতে i < j. তাই 2-to-1 ফাংশনে ভাগের নিয়ম: n(n − 1)/2. - তিন স্তর: i < j < k এমন triple. তিনটি আলাদা সংখ্যার ক্রমযুক্ত triple n(n − 1)(n − 2)টি, আর প্রতিটি সেট {i, j, k} তিনটি সংখ্যার 3! = 6টি ক্রমে আসে, যার ঠিক একটি ছোট থেকে বড়। তাই n(n − 1)(n − 2)/6.
শেষ দুটি সংখ্যা আসলে C(n, 2) আর C(n, 3), n-টি থেকে ২টি বা ৩টি বাছাইয়ের উপায়; পর্ব ৩৩-এ এদের পূর্ণ তত্ত্ব আর ভাগের নিয়ম দিয়েই প্রমাণ আসবে। নিচের ব্লক চারটি loop সত্যিই চালিয়ে গোনে আর math.comb-এর সঙ্গে মেলায়। চতুর্থ loop-এ একটি if/else আছে: জোড় i-তে ভেতরের loop n বার চলে, বিজোড় i-তে মাত্র একটি ধাপ।
from math import comb
def count_loops(n):
a = b = c = d = 0
for i in range(n):
for j in range(n):
a += 1 # every ordered pair (i, j)
for i in range(n):
for j in range(i + 1, n):
b += 1 # pairs with i < j
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
c += 1 # triples i < j < k
for i in range(n):
if i % 2 == 0:
for j in range(n):
d += 1 # even i: the inner loop runs n times
else:
d += 1 # odd i: a single step
return a, b, c, d
for n in (4, 10, 20):
a, b, c, d = count_loops(n)
print(f"n={n}: n*n={a}, i<j: {b} (C(n,2)={comb(n, 2)}), "
f"i<j<k: {c} (C(n,3)={comb(n, 3)}), if/else: {d}")আসল আউটপুট (ব্রাউজারের Python):
n=4: n*n=16, i<j: 6 (C(n,2)=6), i<j<k: 4 (C(n,3)=4), if/else: 10
n=10: n*n=100, i<j: 45 (C(n,2)=45), i<j<k: 120 (C(n,3)=120), if/else: 55
n=20: n*n=400, i<j: 190 (C(n,2)=190), i<j<k: 1140 (C(n,3)=1140), if/else: 210
n = 10-এ পূর্ণ জোড়া 100, i < j জোড়া 45 = 10 · 9/2, আর triple 120 = 10 · 9 · 8/6; সবগুলো comb-এর সঙ্গে মিলেছে। শেষ সংখ্যাটি যোগের নিয়ম: জোড় n-এ n/2টি জোড় i, প্রতিটিতে n ধাপ, আর n/2টি বিজোড় i, প্রতিটিতে ১ ধাপ, মোট (n/2) · n + n/2. n = 10-এ 50 + 5 = 55, n = 20-এ 200 + 10 = 210.
i < j loop n = 10,000 অর্ডারে 49,995,000 বার চলে, n2-এর প্রায় অর্ধেক, তাই বৃদ্ধির হার এখনো দ্বিঘাত। Big-O দিয়ে এই বৃদ্ধি প্রকাশ আর তুলনা করা DSA কোর্সের পর্ব ০৪-এর বিষয়, আর হাতে loop গুনে উত্তর বের করার অনুশীলন DSA কোর্সের পর্ব ৬৮-এ। এখানকার ভূমিকা হলো সঠিক সংখ্যাটি দেওয়া; DSA সেটিকে বৃদ্ধির হারে রূপ দেয়।
সব সম্ভাব্য উত্তর পরীক্ষা করা (brute force) মানে পুরো search space ঘুরে দেখা, আর গুণের নিয়ম তার আকার বলে: n উপাদানের subset 2nটি, ক্রম n!টি। n = 60-এ 260 ≈ 1.15 × 1018, সেকেন্ডে শত কোটি পরীক্ষাতেও কয়েক দশক। পর্ব ২৭-এর key space গোনাও এই একই প্রশ্ন ছিল।
৮ · সাধারণ ভুল, পরীক্ষার অঙ্ক আর একটি ভুল প্রমাণ
গণনার প্রায় সব ভুল চার ধরনের। প্রতিটির একটি ছোট লক্ষণ আছে, যা দেখে সন্দেহ করা যায়।
| ভুল | উদাহরণ | প্রতিকার |
|---|---|---|
| গুণের জায়গায় যোগ | ৩ শার্ট আর ৪ প্যান্টে পোশাক “7টি” | প্রশ্ন করুন: একটি ফল কি দুটি বাছাই মিলে? তাহলে গুণ: 12 |
| যোগের জায়গায় গুণ | ৩ বিস্কুট “অথবা” ৪ কেকে একটি নাশতা “12টি” | একটি ফলে একটিই বাছাই হলে যোগ: 7 |
| দুবার গোনা (overcounting) | “অন্তত একটি অঙ্ক”-এ ঘর বেছে অঙ্ক বসানো; মিল থাকা দুই দল সরল যোগ | complement, বা বিয়োগের নিয়ম; ছোট উদাহরণে brute force |
| ক্রম ভুল বোঝা | অধিনায়ক-সহ-অধিনায়ক (ক্রম আছে) আর “দুজন ওপেনার” (ক্রম নেই) একই ভাবা | দুটি ফল অদলবদল করলে নতুন ফল হয় কি না দেখুন; না হলে ভাগের নিয়ম |
| সমান নয় এমন শ্রেণিতে ভাগ | RRBB আংটিতে “6/4” | প্রতিটি শ্রেণির আকার সমান কি না যাচাই; না হলে ক্ষেত্রভেদে গোনা |
এবার পরীক্ষার ধাঁচের চারটি অঙ্ক; প্রতিটি সংখ্যা scratch-এ brute force করে মেলানো।
অঙ্ক ১: 1 থেকে 1000-এর মধ্যে কতগুলো সংখ্যা 3 অথবা 5 দিয়ে বিভাজ্য?
- A = 3-এর গুণিতক: ⌊1000/3⌋ = 333টি। B = 5-এর গুণিতক: ⌊1000/5⌋ = 200টি। এখানে ⌊x⌋ মানে x-এর চেয়ে বড় নয় এমন বৃহত্তম পূর্ণসংখ্যা।
- A ∩ B = 3 আর 5 দুটি দিয়েই বিভাজ্য = 15-এর গুণিতক (3 আর 5 সহমৌলিক): ⌊1000/15⌋ = 66টি।
- বিয়োগের নিয়মে 333 + 200 − 66 = 467.
অঙ্ক ২: ৪ অঙ্কের PIN-এ (0000 থেকে 9999) অন্তত একটি অঙ্ক পুনরাবৃত্ত হয়, এমন PIN কয়টি?
- মোট PIN: প্রতিটি ঘরে ১০টি, 104 = 10000.
- Complement “সব অঙ্ক আলাদা”: 10 · 9 · 8 · 7 = 5040 (প্রতি ধাপে আগের অঙ্কগুলো বাদ, পছন্দের সংখ্যা স্থির)।
- উত্তর 10000 − 5040 = 4960, প্রায় অর্ধেক PIN.
অঙ্ক ৩: 1 থেকে 999-এর মধ্যে কতগুলো সংখ্যার সব অঙ্ক আলাদা?
- অঙ্কের সংখ্যা অনুযায়ী তিনটি বিচ্ছিন্ন দল (যোগের নিয়ম)।
- ১ অঙ্ক: 1–9, ৯টি। ২ অঙ্ক: প্রথম অঙ্ক 0 হতে পারে না (৯টি), দ্বিতীয়টি প্রথমটি বাদে যেকোনো (৯টি, 0 সহ): 81.
- ৩ অঙ্ক: 9 · 9 · 8 = 648. মোট 9 + 81 + 648 = 738.
অঙ্ক ৪: ১৫ জনের স্কোয়াড থেকে একজন অধিনায়ক আর একজন সহ-অধিনায়ক, আবার আলাদাভাবে দুজন ওপেনিং ব্যাটসম্যান। দুটি সংখ্যা কত?
- অধিনায়ক ১৫ জনের যেকোনো একজন, সহ-অধিনায়ক বাকি ১৪ জনের একজন: 15 · 14 = 210. এখানে ক্রম গুরুত্বপূর্ণ, কারণ দুটি পদ আলাদা।
- দুজন ওপেনারে পদের পার্থক্য নেই (ধরে নিচ্ছি কে প্রথম বল খেলবেন, তা আলাদা সিদ্ধান্ত)। ক্রমযুক্ত 210টি জোড়ার প্রতিটি অক্রমিক জোড়া দুবার আসে, তাই ভাগের নিয়মে 210/2 = 105.
প্রমাণের ভুল ধরুন: “আংটির রং গোনা”
একজন লিখলেন: “দাবি: ২টি লাল আর ২টি নীল পুঁতি দিয়ে একটি আংটি (শুধু ঘোরানো চলে) 6/4 = 1.5 উপায়ে বানানো যায়, তাই উত্তর ভগ্নাংশ বলে প্রশ্নটি ভুল। প্রমাণ: সারিতে সাজানো যায় ৬ উপায়ে (RRBB, RBRB, RBBR, BRRB, BRBR, BBRR). আংটি ৪ রকম ঘোরানো যায়, তাই প্রতিটি আংটি ৪টি সারি থেকে আসে। ভাগের নিয়মে 6/4. ∎” পড়ে ভুলটি নিজে খুঁজুন।
ভুল কোথায়: “প্রতিটি আংটি ৪টি সারি থেকে আসে” দাবিটি মিথ্যা, অথচ উপপাদ্য ৬.২-এর শর্ত (f হলো k-to-1, প্রতিটি preimage-এর আকার k) ঠিক এটিই চায়। RBRB-কে ২ ধাপ ঘোরালে আবার RBRB, তাই তার শ্রেণিতে মাত্র ২টি সারি (RBRB, BRBR). অন্য শ্রেণিতে ৪টি (RRBB, RBBR, BBRR, BRRB). 4 + 2 = 6, আর আংটি ২টি। একটি ভগ্নাংশ উত্তর সবসময় সংকেত দেয় যে কোনো নিয়মের শর্ত ভাঙা হয়েছে; প্রশ্ন নয়, প্রমাণটিই ভুল।
আরও গভীরে: যোগ, গুণ আর bijection-এর নিয়মগুলো অসীম সেটেও অর্থ রাখে, তখন তারা cardinal arithmetic হয়ে যায় (পর্ব ১৮-এ ℵ0 · ℵ0 = ℵ0-এর মতো ফল)। আবার গণনা নিজেই একটি গণনাগত জটিলতার প্রশ্ন: Leslie Valiant ১৯৭৯ সালে #P (“number-P”) শ্রেণি সংজ্ঞায়িত করে দেখান যে একটি bipartite graph-এ perfect matching আছে কি না polynomial সময়ে জানা যায়, কিন্তু কয়টি আছে তা গোনা (matrix-এর permanent) #P-complete, অর্থাৎ সাধারণভাবে দ্রুত গোনার পদ্ধতি থাকার সম্ভাবনা খুবই কম বলে বিশ্বাস করা হয়। গোনা অনেক সময় খোঁজার চেয়ে কঠিন।
পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:
- যোগ আর গুণের নিয়মের পার্থক্য কী? একটি ফলে একটি বাছাই আর দলগুলো বিচ্ছিন্ন হলে যোগ; একটি ফল কয়েকটি ধাপের বাছাই মিলে, আর প্রতি ধাপে পছন্দের সংখ্যা স্থির হলে গুণ।
- ৮ bit-এর কতগুলো string 1 দিয়ে শুরু অথবা 00 দিয়ে শেষ? 128 + 64 − 32 = 160.
- n জন গোল টেবিলে কত উপায়ে বসেন? (n − 1)!, কারণ n! সারির প্রতিটি টেবিলে ঠিক n-টি ঘোরানো রূপ।
- “অন্তত একটি” কীভাবে গোনেন? মোট থেকে “একটিও নয়” বাদ দিয়ে (complement).
for i in range(n): for j in range(i+1, n)কতবার চলে? n(n − 1)/2, i ≠ j এমন ক্রমযুক্ত জোড়া ভাগ 2.
৯ · AI-এর যুগে — গণনার উত্তর আর প্রমাণ যাচাই
গণনার প্রশ্নে AI সহকারীর ব্যাখ্যা যুক্তিসংগত শোনালেও সংখ্যাটি প্রায়ই ভুল হয়, কারণ দুবার গোনা বা বাদ পড়া শর্ত লেখায় চোখে পড়ে না। কয়েকটি ভুল নিয়মিত দেখা যায়:
| AI-এর ভুল | কীভাবে ধরবেন |
|---|---|
| “অন্তত একটি” প্রশ্নে ঘর বেছে বসিয়ে overcounting, বা মিল থাকা দলগুলো সরল যোগ | ছোট alphabet আর ছোট দৈর্ঘ্যে itertools.product দিয়ে সব গুনে মেলান |
| off-by-one: 1 থেকে n নাকি 0 থেকে n − 1, “অন্তত” নাকি “বেশি”, প্রথম অঙ্ক 0 হতে পারে কি না | প্রশ্নের প্রতিটি শব্দ আলাদা করে শর্তে লিখুন; সীমার কাছের ছোট উদাহরণ পরীক্ষা করুন |
| ক্রম উপেক্ষা: ক্রমযুক্ত আর অক্রমিক বাছাই গুলিয়ে ফেলা | দুটি ফল অদলবদল করলে নতুন ফল হয় কি না জিজ্ঞেস করুন; brute force-এ set বা sorted দিয়ে দেখুন |
| শর্ত ছাড়া নিয়ম: সমান নয় এমন শ্রেণিতে ভাগ, বা বিচ্ছিন্ন নয় এমন দলে যোগ | প্রতিটি নিয়মের শর্ত (বিচ্ছিন্ন? স্থির সংখ্যা? k-to-1?) উত্তরে আলাদা করে লিখতে বলুন |
| আত্মবিশ্বাসী কিন্তু ভুল প্রমাণ: “স্পষ্টতই”, বৃত্তাকার যুক্তি, induction-এর ভিত্তি বাদ | প্রতিটি ধাপের কারণ খুঁজুন; ছোট n-এ সূত্রটি একটি counterexample খোঁজার কোডে চালান |
| বড় সংখ্যার পাটিগণিত ভুল, বা বানানো উৎস ও ইতিহাস | Python-এর পূর্ণসংখ্যায় নিজে হিসাব করুন; সাল আর নাম বিশ্বস্ত পাঠ্যবইয়ে মিলিয়ে নিন |
AI-এর কাছে একটি গণনার সমাধান চাইলে এমন কাঠামো দিন, যাতে প্রতিটি ধাপ আলাদা করে পরীক্ষা করা যায়:
AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট
গণনার প্রায় প্রতিটি দাবি ছোট মাপে কয়েক লাইনের কোডে পরীক্ষা করা যায়। দুটি ভিন্ন পথে (যেমন সরাসরি আর complement, বা ভাগের নিয়ম আর একজনকে স্থির করা) একই উত্তর পেলে আস্থা অনেক বাড়ে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১দক্ষিণ এশিয়ার প্রাচীন ছন্দশাস্ত্র আর চিকিৎসাশাস্ত্রে গণনার কোন নিয়মগুলো দেখা যায়, আর সেই ইতিহাস কীভাবে সাবধানে পড়া উচিত?
সংস্কৃত ছন্দশাস্ত্রে প্রতিটি অক্ষর (syllable) হয় লঘু (ছোট) নয় গুরু (দীর্ঘ)। পিঙ্গলের ছন্দঃসূত্রে, যার রচনাকাল সম্পর্কে পণ্ডিতদের মত ভিন্ন (সাধারণত খ্রিস্টপূর্বাব্দের কয়েক শতক আগে বলে ধরা হয়), n অক্ষরের সব ছন্দ-নকশা তালিকা করার (প্রস্তার) আর গোনার নিয়ম আছে বলে উল্লেখ করা হয়। আধুনিক ভাষায় এটি ঠিক n দৈর্ঘ্যের bit string গোনা, উত্তর 2n, গুণের নিয়মে। এর ভাষ্যে, যেমন দশম শতকের কাছাকাছি হলায়ুধের টীকায়, লঘু-গুরুর সংখ্যা অনুযায়ী নকশা গোনার একটি ত্রিভুজাকার সারণি (মেরু-প্রস্তার) পাওয়া যায় বলে বহু ইতিহাসবিদ লেখেন, যাকে আজ Pascal-এর ত্রিভুজের পূর্বসূরি বলা হয় (পর্ব ৩৪ “Binomial coefficient, Pascal-এর ত্রিভুজ আর combinatorial identity”-এ)। আরেকটি সুন্দর সমস্যা: লঘু ১ মাত্রা আর গুরু ২ মাত্রা ধরলে মোট n মাত্রার নকশা কয়টি? উত্তর Fibonacci সংখ্যা, §৫-এর “11 নেই” bit string-এর মতো একই recurrence. এই পর্যবেক্ষণ বিরহাঙ্ক, গোপাল আর হেমচন্দ্রের নামের সঙ্গে যুক্ত বলে উল্লেখিত, Fibonacci-র ১২০২ সালের বইয়ের আগেই।
চিকিৎসাশাস্ত্রে সুশ্রুত সংহিতায় ছয়টি রস (মিষ্ট, অম্ল, লবণ, কটু, তিক্ত, কষায়) থেকে মোট ৬৩টি সংমিশ্রণের কথা আছে বলে প্রায়ই উদ্ধৃত হয়। ৬৩ = 26 − 1: ছয়টি রসের প্রতিটি থাকতে বা না থাকতে পারে (গুণের নিয়মে 26), আর “কোনো রসই নেই” বাদ (complement). দ্বাদশ শতকে ভাস্করাচার্যের লীলাবতীতে অঙ্ক সাজানোর সংখ্যা ধরনের প্রশ্ন আছে বলেও জানা যায়।
তবে দুটি সাবধানতা জরুরি। প্রাচীন গ্রন্থের তারিখ আর পরবর্তী সংযোজন নিয়ে বিতর্ক আছে, তাই নির্দিষ্ট সাল নিয়ে দৃঢ় দাবি এড়ানো উচিত। আর আধুনিক সূত্র পুরোনো লেখায় “পড়ে নেওয়া” আর লেখকেরা যা ভেবেছিলেন, তা আলাদা। একই রকম গণনা পারস্য, আরব, চীন আর ইউরোপেও স্বাধীনভাবে এসেছে।
মূল উপলব্ধি: যোগ, গুণ আর complement-এর নিয়ম বহু সংস্কৃতিতে বাস্তব প্রশ্ন (ছন্দ, ওষুধ, সংখ্যা) থেকে জন্মেছে; ইতিহাস জানা মজার, কিন্তু তারিখ আর কৃতিত্ব নিয়ে দাবি সূত্রের মতোই যাচাই করে বলা উচিত।
প্র ০২“password-এ অন্তত একটি অঙ্ক, একটি বড় হাতের অক্ষর আর একটি চিহ্ন থাকতে হবে”, এমন নিয়ম গণনার দিক থেকে কী করে, আর আধুনিক নির্দেশিকা কেন দৈর্ঘ্যের ওপর বেশি জোর দেয়?
গণনার দিক থেকে উত্তরটি অপ্রত্যাশিত: এমন রচনা-নিয়ম (composition rule) সম্ভাব্য password-এর সংখ্যা কমায়, বাড়ায় না। §৪-এর হিসাবে ৬–৮ দৈর্ঘ্যের সব 36-চিহ্নের string ছিল প্রায় 2.9 × 1012; “অন্তত একটি অঙ্ক” শর্ত তা থেকে শুধু-অক্ষরের string বাদ দিয়ে 2.68 × 1012-এ নামিয়েছে। প্রতিটি নতুন শর্ত complement-এর মতো একটি অংশ ছেঁটে ফেলে। নিয়মগুলোর যুক্তি ছিল মানুষের আচরণ: শর্ত দিলে হয়তো মানুষ অনুমানযোগ্য শব্দ থেকে সরে আসবেন।
অভিজ্ঞতা দেখিয়েছে, মানুষ শর্ত মানেন অনুমানযোগ্য উপায়ে: শুরুতে বড় হাতের অক্ষর, শেষে “1” বা “!”. তাই আক্রমণকারীর অনুমানের তালিকায় এই নকশাগুলো আগেই থাকে, আর বাস্তব নিরাপত্তা সামান্যই বাড়ে। অন্যদিকে দৈর্ঘ্যের প্রভাব গুণের নিয়মে সূচকীয়: প্রতিটি অতিরিক্ত ঘর সম্ভাবনাকে alphabet-এর আকার দিয়ে গুণ করে। 368 থেকে 3612-এ যাওয়া মানে প্রায় 17 লাখ গুণ বৃদ্ধি, যেখানে ৮ ঘরে alphabet 36 থেকে 62 করলে বৃদ্ধি মোটামুটি 77 গুণ (এই অনুপাত দুটি scratch-এ হিসাব করা)।
এই কারণে মার্কিন প্রতিষ্ঠান NIST-এর ডিজিটাল পরিচয় বিষয়ক নির্দেশিকা SP 800-63B (২০১৭) রচনা-নিয়ম চাপানোর বিরুদ্ধে পরামর্শ দেয়, আর দৈর্ঘ্য, ফাঁস হওয়া password-এর তালিকার সঙ্গে মিলিয়ে দেখা আর পর্যায়ক্রমিক জোর করে বদলানো বন্ধের দিকে জোর দেয় বলে ব্যাপকভাবে উদ্ধৃত; পরবর্তী সংশোধনে একই অবস্থান আরও কড়া ভাষায় এসেছে বলে প্রতিবেদন আছে। বিস্তারিত ব্যবহারিক আলোচনা Cybersecurity কোর্সের পর্ব ১৫-এ। গণনা এখানে একটি সীমাও দেখায়: সম্ভাব্য সংখ্যা নিরাপত্তার ঊর্ধ্বসীমা মাত্র, বাস্তব নিরাপত্তা নির্ভর করে মানুষ কীভাবে বাছেন, যা সম্ভাবনা আর entropy-র প্রশ্ন।
মূল উপলব্ধি: একটি নিয়ম “শক্ত” শোনালেও গণনা দিয়ে তার প্রভাব মাপা যায়; গুণের নিয়ম বলে দৈর্ঘ্য সূচকীয়ভাবে কাজ করে, আর বাস্তব আচরণ বলে শর্তগুলো প্রায়ই অনুমানযোগ্যতা বাড়ায়।
প্র ০৩ভাগের নিয়ম গোল টেবিলে নিখুঁত কাজ করে, কিন্তু একই রঙের পুঁতির আংটিতে ব্যর্থ। এই ব্যর্থতা গণিতকে কোন দিকে নিয়ে গেছে?
গোল টেবিলে প্রতিটি মানুষ আলাদা, তাই কোনো ঘোরানো (শূন্য ঘোরানো ছাড়া) কোনো বসার ব্যবস্থাকে অপরিবর্তিত রাখে না, আর প্রতিটি শ্রেণিতে ঠিক n-টি সারি। একই রঙের পুঁতিতে কিছু নকশা নিজেই প্রতিসম: RBRB দুই ধাপ ঘোরালে একই থাকে। প্রতিসম নকশার শ্রেণি ছোট, তাই সমান ভাগ ভেঙে পড়ে। এটি কোনো বিচ্ছিন্ন কৌতূহল নয়: রসায়নে একটি অণুর কতগুলো আলাদা isomer আছে, একটি ঘনকের ছয় তলে তিন রং কতভাবে দেওয়া যায় (ঘোরানো একই ধরে), একটি graph-এর কতগুলো “আলাদা আকৃতি” আছে, সবই প্রতিসমতাসহ গণনার প্রশ্ন।
সমাধানটি group theory থেকে আসে। ঘোরানোগুলো একটি group গঠন করে, আর প্রতিটি নকশার “stabilizer” (যে ঘোরানোগুলো তাকে বদলায় না) ও “orbit” (যে নকশাগুলোয় তাকে নেওয়া যায়) গুণফল সবসময় group-এর আকার। এই orbit-stabilizer সম্পর্ক থেকে আসে Burnside-এর lemma: শ্রেণির সংখ্যা = প্রতিটি group উপাদান যতগুলো নকশা স্থির রাখে, তার গড়। RRBB আংটিতে (6 + 0 + 2 + 0)/4 = 2. নামটি William Burnside-এর ১৮৯৭ সালের বই থেকে জনপ্রিয় হলেও ফলটি আগে Cauchy আর Frobenius জানতেন বলে উল্লেখ করা হয়, তাই কেউ কেউ একে “Burnside-এর নয় এমন lemma” বলেন। George Pólya ১৯৩৭ সালের দিকে এটিকে একটি শক্তিশালী গণনা-তত্ত্বে রূপ দেন, যা রাসায়নিক যৌগ গোনায় ব্যবহৃত হয়েছিল বলে জানা যায়; J. H. Redfield-এর আগের (১৯২৭) কাজও স্বাধীনভাবে অনুরূপ ছিল বলে পরে স্বীকৃত হয়।
লক্ষ করুন, ভাগের নিয়ম এই তত্ত্বের বিশেষ ক্ষেত্র: যখন শূন্য ঘোরানো ছাড়া কেউ কিছু স্থির রাখে না, গড়টি |A|/|G|. এই পূর্ণ গল্প পর্ব ৫১ “Symmetry দিয়ে গণনা — Burnside-এর lemma আর Pólya”-এ।
মূল উপলব্ধি: একটি সহজ নিয়মের শর্ত ঠিক কোথায় ভাঙে, তা খুঁজলে প্রায়ই একটি গভীর তত্ত্বের দরজা খোলে; ভাগের নিয়মের “সমান শ্রেণি” শর্ত থেকেই প্রতিসমতার গণনা শুরু।
প্র ০৪গুণের নিয়ম বলে search space কত দ্রুত বড় হয়। এটি cryptography আর algorithm নকশায় কী সিদ্ধান্ত নিতে সাহায্য করে, আর কোথায় এর সীমা?
গুণের নিয়মের সবচেয়ে বড় বার্তা হলো সূচকীয় বৃদ্ধি: n bit-এর key-এর সংখ্যা 2n, n জিনিসের ক্রম n!. Cryptography এটিকে প্রতিরক্ষা হিসেবে ব্যবহার করে। AES-128-এর key space 2128 ≈ 3.4 × 1038; প্রতি সেকেন্ডে 1018টি key পরীক্ষা করা কাল্পনিক যন্ত্রেরও সব key দেখতে মহাবিশ্বের বয়সের চেয়ে বহু গুণ বেশি সময় লাগবে। পর্ব ২৭-এর shift cipher-এ মাত্র ২৬টি key ছিল, তাই হাতেই ভাঙা যেত; substitution cipher-এ 26! ≈ 4 × 1026টি key, তবু frequency analysis দিয়ে ভাঙা যায়। এই দ্বিতীয় তথ্যটিই সীমা দেখায়: বিশাল search space প্রয়োজনীয়, কিন্তু যথেষ্ট নয়। কাঠামো থাকলে আক্রমণকারী পুরো space না ঘুরে কাঠামো ব্যবহার করেন।
Algorithm নকশায় একই সংখ্যা উল্টো দিকে কাজ করে। ভ্রমণকারী বিক্রেতার মতো সমস্যায় n শহরের সব রুট পরীক্ষা করতে (n − 1)!/2টি চক্র লাগে (n ≥ 3, শুরুর শহর স্থির আর দিক উল্টালে একই, ঠিক §৬-এর ভাগের নিয়ম)। ২০টি শহরে তা প্রায় 6 × 1016. তাই গণনা আগেই বলে দেয় brute force অসম্ভব, আর তখন dynamic programming, branch and bound, backtracking-এর ছাঁটাই বা আনুমানিক পদ্ধতির দিকে যেতে হয় (DSA কোর্সের পর্ব ৫৬)। ছাঁটাইয়ের কার্যকারিতা বোঝাতেও গণনা লাগে: §৫-এর tree-তে “11” কেটে ৪ bit-এ 16 থেকে 8-এ নেমেছিল, আর n বড় হলে বৈধ string মোটের তুলনায় সূচকীয়ভাবে কম।
সীমাটি আবার মনে রাখা দরকার: search space-এর আকার একটি ঊর্ধ্বসীমা দেয়, নিম্নসীমা নয়। কোনো সমস্যার জন্য brute force-এর চেয়ে ভালো algorithm আছে কি না, সেটি অনেক কঠিন প্রশ্ন, যার কেন্দ্রে P বনাম NP (DSA কোর্সের পর্ব ৬৪)।
মূল উপলব্ধি: গুণের নিয়ম দিয়ে search space গুনে নেওয়া যেকোনো নকশার প্রথম কাজ; তবে বিশাল সংখ্যা শুধু বলে “সব ঘুরে দেখা অসম্ভব”, বলে না “কোনো চতুর পথ নেই”।
প্র ০৫কম্পিউটার যখন সব কিছু brute force করে গুনতে পারে, তখন গণনার সূত্র আর প্রমাণ কেন দরকার?
প্রথম কারণ মাপ। এই পর্বের ব্লকগুলো ছোট n-এ চলেছে, কারণ সূচকীয় search space দ্রুত যেকোনো কম্পিউটারের নাগালের বাইরে যায়। ৮ দৈর্ঘ্যের password গুনতে brute force-এ প্রায় 2.8 × 1012টি string পরীক্ষা লাগত, সূত্রে তিনটি ঘাত। একটি চমকপ্রদ উদাহরণ Dedekind সংখ্যা: n চলকের monotone Boolean function-এর সংখ্যা। ১৮৯৭ সালে Richard Dedekind প্রশ্নটি তোলেন, আর n = 9-এর মান ২০২৩ সালে দুটি আলাদা গবেষক দল সুপারকম্পিউটার আর চতুর গাণিতিক সংক্ষেপণ মিলিয়ে বের করেছে বলে প্রকাশিত; শুধু brute force দিয়ে এটি সম্ভব ছিল না। সূত্র বা কাঠামো ছাড়া কম্পিউটারও থেমে যায়।
দ্বিতীয় কারণ সাধারণতা। brute force শুধু একটি নির্দিষ্ট n-এর উত্তর দেয়; সূত্র সব n-এর উত্তর দেয়, আর প্রমাণ বলে কেন। ব্লক ৩ n = 3 থেকে 7 পর্যন্ত (n − 1)! মিলিয়েছিল, কিন্তু n = 100-এ সত্য কি না, তা শুধু উপপাদ্য ৬.২-এর প্রমাণই নিশ্চিত করে। ইতিহাসে এমন অনুমান আছে, যা প্রথম বহু ক্ষেত্রে সত্য হয়েও পরে ভেঙেছে, যেমন বৃত্তে n বিন্দু যোগ করে অঞ্চল গোনার প্রশ্নে 1, 2, 4, 8, 16-এর পরে 32 নয়, 31 আসে। তৃতীয় কারণ বোঝা। tree-এর Fibonacci ধারা brute force-এ শুধু একটি সংখ্যার তালিকা; যোগের নিয়মে শেষ bit অনুযায়ী ভাগ করলে বোঝা যায় ধারাটি কেন এমন, আর সেই বোঝা নতুন সমস্যায় স্থানান্তর করা যায়।
তবে brute force শত্রু নয়, সহকর্মী। ছোট ক্ষেত্রের সংখ্যা ধারা বের করে OEIS (On-Line Encyclopedia of Integer Sequences)-এর মতো তালিকায় মিলিয়ে অনুমান তৈরি হয়, আর প্রমাণে কোনো ভুল থাকলে brute force প্রায়ই প্রথম counterexample দেয়। এই পর্বের প্রতিটি সূত্র দুইভাবেই এসেছে: প্রমাণ আর যন্ত্রে যাচাই।
মূল উপলব্ধি: brute force ছোট ক্ষেত্রে সত্য দেখায় আর ভুল ধরে; প্রমাণ সব ক্ষেত্রে সত্য নিশ্চিত করে আর কারণ বোঝায়। দুটি মিলেই নির্ভরযোগ্য গণনা।
অনুশীলন
আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।
-
প্রমাণ: n ≥ 1 হলে n দৈর্ঘ্যের যে bit string-এ 1-এর সংখ্যা জোড়, তাদের সংখ্যা ঠিক 2n−1. একটি bijection বা ভাগের নিয়ম দিয়ে প্রমাণ করুন।
- E = জোড় সংখ্যক 1 আছে এমন string, O = বিজোড় সংখ্যক 1. E আর O বিচ্ছিন্ন, আর E ∪ O = সব string, তাই যোগের নিয়মে |E| + |O| = 2n. — উপপাদ্য ২.১ আর ৩.১
- g: E → O, g(w) = w-এর শেষ bit উল্টানো। শেষ bit উল্টালে 1-এর সংখ্যা ঠিক ১ বাড়ে বা কমে, তাই জোড় থেকে বিজোড় হয়: g সত্যিই O-তে যায়। — n ≥ 1 বলে শেষ bit আছে
- একই নিয়ম O → E-তে g-এর inverse, কারণ দুবার উল্টালে আগের string. তাই g একটি bijection, আর |E| = |O|. — পর্ব ১৬
- |E| = |O| = 2n/2 = 2n−1. ∎
বিকল্প: প্রথম n − 1টি bit যেকোনো, আর শেষ bit ঠিক একভাবে নির্ধারিত; গুণের নিয়মে 2n−1 · 1. n = 1 থেকে 6-এ brute force-এ 1, 2, 4, 8, 16, 32 মিলেছে। n = 0-এ উত্তর 1, যা 2−1 নয়, তাই শর্ত n ≥ 1.
-
হিসাব: বাজারঘর password নীতি বদলাল: দৈর্ঘ্য ৪ বা ৫, চিহ্ন a–z আর 0–9, আর অন্তত একটি অঙ্ক এবং অন্তত একটি অক্ষর থাকতে হবে। কতগুলো password সম্ভব?
n দৈর্ঘ্যে মহাবিশ্ব 36n. খারাপ string দুই ধরনের: “শুধু অক্ষর” (26n) আর “শুধু অঙ্ক” (10n). একটি string একসঙ্গে দুটি হতে পারে না (n ≥ 1-এ অন্তত একটি চিহ্ন আছে), তাই দুটি বিচ্ছিন্ন, আর বৈধ = 36n − 26n − 10n.
n = 4: 1679616 − 456976 − 10000 = 1,212,640. n = 5: 60466176 − 11881376 − 100000 = 48,484,800. দৈর্ঘ্য অনুযায়ী যোগ: 49,697,440. ছোট রূপে (a, b, 0, 1, দৈর্ঘ্য ৩) সূত্র 43 − 23 − 23 = 48, brute force-ও 48 (scratch-এ যাচাই করা)।
-
আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
cnt = 0 for i in range(5): for j in range(i, 5): cnt += 1 print(cnt, 5 * 6 // 2)15 15ভেতরের loop j = i থেকে শুরু, তাই i ≤ j এমন জোড়া গোনা হচ্ছে। i = 0-এ ৫ বার, i = 1-এ ৪, তারপর ৩, ২, ১: মোট 5 + 4 + 3 + 2 + 1 = 15. অন্যভাবে: i < j জোড়া 5 · 4/2 = 10, আর i = j জোড়া 5টি, বিচ্ছিন্ন দুই দল, যোগের নিয়মে 15 = 5 · 6/2. সাধারণভাবে n(n + 1)/2.
-
প্রমাণের ভুল ধরুন: একজন লিখলেন: “বাজারঘরের সভাকক্ষে একটি গোল টেবিল, যার চেয়ারগুলোতে ১ থেকে ৪ নম্বর লেখা। ৪ জনকে বসানোর উপায়: সারিতে 4! = 24, আর গোল টেবিলে প্রতিটি ব্যবস্থা ৪ বার গোনা হয়, তাই ভাগের নিয়মে 24/4 = 6.” ভুলটি কোথায়, আর সঠিক উত্তর কত?
চেয়ারে নম্বর থাকলে প্রতিটি চেয়ার আলাদা অবস্থান, আর সবাই এক চেয়ার ঘুরে বসলে প্রত্যেকের চেয়ার নম্বর বদলে যায়; তাই সেটি নতুন ব্যবস্থা। “একই ব্যবস্থার ৪টি রূপ” বলে কিছু নেই, অর্থাৎ ফাংশনটি 4-to-1 নয়, 1-to-1. সঠিক উত্তর: চেয়ার ১-এ ৪ জনের একজন, চেয়ার ২-এ বাকি ৩ জনের একজন, …, গুণের নিয়মে 4! = 24. ভাগের নিয়ম শুধু তখন, যখন প্রশ্ন বলে “শুধু কে কার পাশে, তা-ই গুরুত্বপূর্ণ”; তখন (4 − 1)! = 6. শিক্ষা: ভাগ করার আগে লিখে নিন কোন দুটি ফলকে “একই” ধরা হচ্ছে, আর প্রতিটি শ্রেণিতে ঠিক কয়টি রূপ।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রম“৬–৮ দৈর্ঘ্যের password, অন্তত একটি অঙ্ক” গোনার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- গোনার সেটটি নিখুঁতভাবে লেখা: কোন চিহ্ন, কোন দৈর্ঘ্য, কোন শর্ত
- দৈর্ঘ্য অনুযায়ী বিচ্ছিন্ন দলে ভাগ করা (যোগের নিয়ম)
- প্রতিটি দৈর্ঘ্যে সব string গোনা: 36n (গুণের নিয়ম)
- প্রতিটি দৈর্ঘ্যে complement “একটিও অঙ্ক নেই” 26n বাদ দেওয়া
- তিন দৈর্ঘ্যের ফল যোগ করে ছোট রূপে brute force দিয়ে যাচাই করা
একটি দোকানে ৫ রকম শার্ট আর ৪ রকম প্যান্ট আছে। একটি শার্ট আর একটি প্যান্ট মিলিয়ে কতগুলো আলাদা পোশাক বানানো যায়?
- 9
- 16
- 20
- 625
৪ অঙ্কের PIN (0000 থেকে 9999)-এ অন্তত একবার 7 আছে, এমন PIN কয়টি?
- 4000
- 3439
- 6561
- 5040
৮ bit-এর কতগুলো string 1 দিয়ে শুরু হয় অথবা 00 দিয়ে শেষ হয়?
- 192
- 128
- 32
- 160
৫ জন বন্ধু একটি গোল টেবিলে বসবেন; চেয়ারে নম্বর নেই, শুধু কে কার পাশে বসেন তা গুরুত্বপূর্ণ (ঘড়ির কাঁটার দিক আর উল্টো দিক আলাদা ধরা হয়)। কত উপায়ে বসা যায়?
- 24
- 120
- 12
- 5
নিচের Python কোডে n = 20 হলে cnt-এর শেষ মান কত?for i in range(n): for j in range(i + 1, n): cnt += 1 (শুরুতে cnt = 0)
- 400
- 380
- 190
- 210
ভাগের নিয়ম |B| = |A|/k প্রয়োগের জন্য ফাংশন f: A → B সম্পর্কে কোন শর্তটি অবশ্যই দরকার?
- B-এর উপাদানগুলোর গড়ে k-টি করে preimage থাকলেই চলে
- B-এর প্রতিটি উপাদানের ঠিক k-টি preimage থাকতে হবে
- f অবশ্যই one-to-one হতে হবে
- f শুধু onto হলেই যথেষ্ট
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- যোগ: জোড়ায় জোড়ায় বিচ্ছিন্ন সেটে |A1 ∪ ⋯ ∪ Am| = ∑|Ai|. মিল থাকলে বিয়োগের নিয়ম |A ∪ B| = |A| + |B| − |A ∩ B|.
- গুণ: |A1 × ⋯ × Am| = ∏|Ai|; কাজের রূপে প্রতিটি ধাপে পছন্দের সংখ্যা স্থির থাকতে হবে, পছন্দের সেট বদলালেও চলে। string nk, ফাংশন nm, subset 2n.
- Complement: |A| = |U| − |Ā|. “অন্তত একটি” মানে মোট বাদ “একটিও নয়”: password 36n − 26n, ৬–৮ দৈর্ঘ্যে 2,684,483,063,360.
- ভাগ: k-to-1 ফাংশনে |B| = |A|/k; n জন গোল টেবিলে (n − 1)!. প্রতিটি শ্রেণি ঠিক k আকারের না হলে ভাগ চলে না (RRBB আংটি).
- Tree আর loop: পছন্দ আগের পছন্দের ওপর নির্ভর করলে tree diagram (“11” নেই এমন ৪ bit: 8টি); i < j loop চলে n(n − 1)/2 বার। প্রতিটি উত্তর ছোট রূপে brute force দিয়ে যাচাই করুন।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৩২ · Pigeonhole principle — সহজ থেকে generalizedপরবর্তী পর্বঅস্তিত্ব প্রমাণের সবচেয়ে সরল আর শক্তিশালী গণনা-যুক্তি।
- পর্ব ১৫ · সেটের অপারেশন — union, intersection, Venn diagram আর identityপুনরালোচনাদুই সেটের inclusion–exclusion, যার ওপর বিয়োগের নিয়ম দাঁড়িয়ে।
- পর্ব ১৬ · ফাংশন — one-to-one, onto, inverse আর compositionপুনরালোচনাফাংশন গোনা, bijection আর pigeonhole-এর প্রথম রূপ।
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের মানচিত্র আর ১৪টি মডিউল।
- DSA · পর্ব ০৪ · বৃদ্ধির হার আর Big-O, Ω, Θকোডে প্রয়োগloop গুনে পাওয়া সংখ্যাকে বৃদ্ধির হারে প্রকাশ।
- AI Foundations · পর্ব ৩৫ · AI-এর জন্য সম্ভাবনা — event, conditional আর independenceপরের ধাপগণনা থেকে সম্ভাবনা: অনুকূল ফল ভাগ মোট ফল।