Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Tuesday, June 1, 2010

যন্ত্র গণকের যন্তর মন্তর - ৩



(পর্ব ১) (পর্ব ২)

সাত্তার সারের ভাত ঘুম

শেষমেশ ভাত ঘুমটা আর জুত করে দেয়া গেলোনা ...

ক্লাস এইট সি-সেকশনের ক্লাস টিচার আবদুস সাত্তার স্যারের আজ মেজাজ বেজায় খারাপ। কলেজিয়েট স্কুলের সবচেয়ে বদমাশ ছাত্রদের ধরে ধরে ভরা হয়েছে এই শাখায়, আর এদের বাঁদরামি সামলাতে হয় উনাকেই। দুপুর পেরুলেই ক্লাস প্রায় ফাঁকা, ক’দিন আগে স্টেশন রোডের এক সিনেমা হল থেকে ৪০ জন ছাত্রকে হাতেনাতে ধরা হয়েছিলো। ইদানিং বেতেও কাজ হচ্ছে না, ছেলেপেলে অবস্থা বুঝে দুটো শার্ট পরে আসে যাতে ব্যথা না লাগে।

এহেন দুরন্ত ছাত্রদের সামলাতেই যেখানে দিন যায়, সেখানে হেড স্যার গোদের উপরে বিষফোঁড়ার মতো করে বাড়তি কাজ চাপিয়ে দিয়েছেন। সামনে স্কুলের বার্ষিক ক্রীড়া প্রতিযোগিতা, তার জন্য মার্চপাস্ট করাতে হবে ছাত্রদের দিয়ে; সাধারণত রশীদ স্যার এ কাজটা করেন, কিন্তু তিনি আজ ছুটিতে। তাই এই বাঁদরদের নিয়ে পিটি প্র্যাকটিস আজ তাঁকেই করতে হবে, কড়া এই দুপুরের রোদে। ছেলেপেলেগুলো প্রচন্ড দুষ্ট – আর তাদেরই কি না উচ্চতার ভিত্তিতে লাইন করে দাঁড় করিয়ে প্যারেড শেখাতে হবে।

প্রচন্ড খারাপ মেজাজ নিয়ে সাত্তার স্যার ক্লাসে ঢুকলেন। বান্দরকুলশিরোমণি ছাত্র শফিককে সামনে পেতেই বেতালেন খানিকক্ষণ। তাতেও মেজাজ ভালো হলো না। বাঁদরগুলোকে লাইন করে ঠিকমতো দাঁড়াতে বললে তারা উলটো মশকরা শুরু করে দেয়, কে কোথায় দাঁড়াবে, তা উনাকেই ঠিক করতে হবে।

সময় হাতে অল্প, এর মধ্যে ৫০টা বাঁদর ছাত্রকে কীভাবে তিনি উচ্চতার ভিত্তিতে সাজাবেন?

----

আসুন, আজ দেখা যাক, সাত্তার স্যারকে আমরা কীভাবে সাহায্য করতে পারি ...

সর্টিং বা বাছাইকরণ

বাছাই করা, অর্থাৎ ক্রমানুসারে সাজানো তথ্য বিশ্লেষণের একটি মৌলিক সমস্যা। এক গাদা সংখ্যাকে ছোট থেকে বড়, কিংবা বড় থেকে ছোট, অথবা অনেকগুলো নামকে বর্ণানুক্রমিকভাবে সাজানো – এরকম সমস্যা আমাদের প্রতিনিয়তই সমাধান করতে হয়। কম্পিউটার বিজ্ঞানে এই সমস্যাটির সমাধানের কৌশলগুলোকে বলে সর্টিং অ্যালগরিদম। আজ আমরা দেখবো এই সর্টিং এর কিছু সহজ কৌশল।

সিলেকশন সর্ট

এই সর্টিং কৌশলের মূল ধারণাটা খুব সহজ। তালিকাকে ছোট থেকে বড়তে সাজাতে হবে? তাহলে প্রথম ধাপে তালিকার সবচেয়ে ছোট সংখ্যাটা খুঁজে নিন। সেটাকে আলাদা করে রাখুন। এবার বাকি গুলো থেকে সবচেয়ে ছোটটি বেছে নিন, আগের সংখ্যাটির পরে রাখুন এটাকে। এভাবে প্রতি ধাপে তালিকার বাকি অংশের সবচেয়ে ছোট সংখ্যা বেছে বেছে নিয়ে পেছনে যোগ করতে থাকুন, তাহলেই পরিশেষে পেয়ে যাবেন ছোট থেকে বড়তে বাছাই করা একটা তালিকা।

ধরা যাক, সাত্তার স্যারের সামনে আছে রফিক, শফিক, হিমাদ্রি, জুয়েল, ফারুক, ও দেবকান্ত। এদের উচ্চতা একেক রকম, রীতিমতো বাটকু শফিক যেমন আছে, সেরকম ঢ্যাঙা গোছের ফারুকও আছে। এদের উচ্চতাগুলো, ইঞ্চিতে, ধরা যাক, (৬৩, ৫৫, ৬৫, ৫২, ৭১, ৫৬)।

তাহলে প্রথম ধাপে আমরা পেলাম সবচেয়ে বেঁটে হলো শফিক, অর্থাত ছোট সংখ্যা, ৫২। শফিককে সাত্তার স্যার বললেন মাঠের মধ্যে লাইনের শুরুতে দাঁড়াতে। (ভেঙচি কাটা দেখে ফেলাতে বাড়তি শাস্তি হিসাবে কান ধরে দাড় করিয়ে রাখলেন)। যাহোক, অংকের হিসেবে ব্যাপারটা দাঁড়ালো এরকম, আমাদের হাতের তালিকার শুরুতে রাখলাম [৫২]। বাকি সংখ্যার তালিকাটা হলো (৬৩, ৫৫, ৬৫, ৭১, ৫৬), আর তার মধ্যে সবচেয়ে ছোট হলো ৫৫। সেটাকে হাতের তালিকার পেছনে রাখলে হয়, [৫২, ৫৫]।

বাকি সংখ্যার তালিকা (৬৩, ৬৫, ৭১, ৫৬), সেখানকার ক্ষুদ্রতম সংখ্যা ৫৬। তাকে বাছাই তালিকার পেছনে দিলে সেটা হয় [৫২, ৫৫, ৫৬]।

বাকি সংখ্যার তালিকা (৬৩, ৬৫, ৭১), সেখানকার ক্ষুদ্রতম সংখ্যা ৬৩। তাকে বাছাই তালিকার পেছনে দিলে সেটা হয় [৫২, ৫৫, ৫৬, ৬৩]।

বাকি সংখ্যার তালিকা (৬৫, ৭১), সেখানকার ক্ষুদ্রতম সংখ্যা ৬৫। তাকে বাছাই তালিকার পেছনে দিলে সেটা হয় [৫২, ৫৫, ৫৬, ৬৩, ৬৫]।

আর বাকি রইলো ৭১, (ক্লাসের সবচেয়ে ঢ্যাঙা ছোকরা গুঁফো ফারুক, তার উচ্চতা এখনই কলেজে পড়া ছেলেদের মতো!!)। ৭১ সেটা তালিকার সবচেয়ে বড় সংখ্যা, তাকে বাছাই তালিকার পেছনে জুড়ে দিলে পাই [৫২, ৫৫, ৫৬, ৬৩, ৬৫, ৭১]। ব্যস, বড় থেকে ছোটতে সাজানো হয়ে গেলো তালিকাটা।

আরেকটা উদাহরণ দেখা যাক নিচের ছবিতে (উৎসঃ উইকিপিডিয়া) -



এভাবে না হয় ৬ জন ছাত্রকে কম থেকে বেশি উচ্চতায় সাজানো গেলো, কিন্তু সময় কেমন লাগলো? এখানে দেখা যাচ্ছে, ছয় জনের জন্য ছয় ধাপ লেগেছে। আবার প্রতি ধাপে বাকি সংখ্যার তালিকার সবচেয়ে ছোটটি বের করতে হয়েছে। কাজেই মোট ছাত্রের সংখ্যা ক হলে এই পদ্ধতিতে সময় লাগছে গড়পড়তায় ক ধাপ x প্রতি ধাপে গড়ে ক’টি তুলনা, মানে গড়পড়তার গোজামিলে কxক।

এর চেয়ে দ্রুতও নিশ্চয় কাজটা করা সম্ভব? ৫০টা বাঁদর ছেলেকে এক এক করে এমন করে সাজাতে গেলে সারা দিন লাগবে, তাই সাত্তার স্যার এবার ক্লাসের ফার্স্ট বয় পার্থ, তাকে ডেকে কাজটা ধরিয়ে দিলেন। উনার আবার দুপুরের ভাতঘুমটা পেয়ে বসেছে।

বাবল সর্ট বা বুদ্বুদ বাছাই

পানি বা সাবান পানির মধ্যে স্ট্র ডুবিয়ে বুদবুদ বানিয়েছেন ছেলেবেলায়? কিংবা এখনো? যদি করে থাকেন তাহলে হয়তো দেখেছেন, বড় বুদবুদ অনেক দ্রুত ভেসে উঠে?

পার্থর মাথায় এলো এই বুদ্ধিটা, এক এক করে কে সবচেয়ে ছোট তা বের না করে অন্য পদ্ধতি খাটাবে। লম্বু কাউকে পেলেই লাইনের পেছনের দিকে ঠেলে দেবে।

যা বুদ্ধি সেই কাজ, পার্থ সবাইকে এক বারে লাইনে দাঁড় করিয়ে ফেললো। এর পর শুরু করলো এই কাজটা, প্রথমজন থেকে শুরু করলো। প্রত্যেককে পরের সাথে তুলনা করে, যদি আগেরজন পরের জনের চাইতে লম্বা হয়, তাহলে লম্বুজনের সাথে বেঁটেজনের জায়গা বদল করে দেয়। এভাবে শেষ জনের আগের জন পর্যন্ত যাবার পরে আবার প্রথম থেকে শুরু করে, তবে এবার শেষ জনের দুইজন আগে গিয়ে অদলবদল বন্ধ করে।

আবারও উদাহরণ হিসাবে (৬৩, ৫৫, ৬৫, ৫২, ৭১, ৫৬) তালিকাটা দেখা যাক।

প্রথম দুইজনের উচ্চতা ৬৩ ও ৫৫, কাজেই লম্বু ৬৩কে দ্বিতীয় স্থানে পাঠানোতে তালিকাটা দাঁড়ালো (৫৫, ৬৩, ৬৫, ৫২, ৭১, ৫৬)। এবারে দ্বিতীয় ও তৃতীয় জনের জোড়া (৬৩, ৬৫) এর মধ্যে ৬৫ লম্বু, কাজেই জায়গা বদলের দরকার নাই। তার পরের জোড়া (৬৫, ৫২) কে জায়গা বদল করে পাই (৫৫, ৬৩, ৫২, ৬৫, ৭১, ৫৬)। তার পরের জোড়া (৬৫, ৭১) ঠিক আছে। সর্বশেষ জোড়া (৭১, ৫৬) কে জায়গা বদল করানোতে পাওয়া গেলো (৫৫, ৬৩, ৫২, ৬৫, ৫৬, ৭১)।

এবার দ্বিতীয় পর্যায়ে একই কাজ শুরু থেকে করতে হবে, কিন্তু সবশেষের জায়গার লম্বু ফারুককে বাদ দিয়ে,

(৫৫, ৬৩, ৫২, ৬৫, ৫৬, ৭১) -> (৫৫, ৬৩, ৫২, ৬৫, ৫৬, ৭১) (১ম দুইজন ঠিক আছে)

(৫৫, ৬৩, ৫২, ৬৫, ৫৬, ৭১) -> (৫৫, ৫২, ৬৩, ৬৫, ৫৬, ৭১) (জায়গাবদল)

(৫৫, ৫২, ৬৩, ৬৫, ৫৬, ৭১) -> (৫৫, ৫২, ৬৩, ৬৫, ৫৬, ৭১) (ঠিক আছে)

(৫৫, ৫২, ৬৩, ৬৫, ৫৬, ৭১) -> (৫৫, ৫২, ৬৩, ৫৬, ৬৫, ৭১) (জায়গাবদল)

এবার ৩য় পর্যায়ে একই কাজ শুরু, কিন্তু সবশেষের লম্বু ফারুক, আর তার আগের হিমাদ্রীকে বাদ দিয়ে।

(৫৫, ৫২, ৬৩, ৫৬, ৬৫, ৭১) -> (৫২, ৫৫, ৬৩, ৫৬, ৬৫, ৭১) (জায়গাবদল)

(৫২, ৫৫, ৬৩, ৫৬, ৬৫, ৭১) -> (৫২, ৫৫, ৬৩, ৫৬, ৬৫, ৭১) (ঠিক আছে)

(৫২, ৫৫, ৬৩, ৫৬, ৬৫, ৭১) -> (৫২, ৫৫, ৫৬, ৬৩, ৬৫, ৭১) (জায়গাবদল)

এবার ৪র্থ পর্যায়েও একই কাজ শুরু, কিন্তু শেষের তিনজনকে বাদ দিয়ে। এভাবে করতে থাকলে আর দুই ধাপ পরেই আমরা পাবো সাজানো তালিকাটি, (৫২, ৫৫, ৫৬, ৬৩, ৬৫, ৭১)।



(বাবল সর্টের অ্যানিমেশন - উইকিপিডিয়া)

পার্থ অবশ্য এতো দূর যেতে পারেনি। স্যার একটু তন্দ্রাতে যেতেই ফারুক পার্থকে মনের সুখে কিছুক্ষণ গাট্টা দিলো। আঁতেল পোলার মাতব্বরী এই রোদে আর কাঁহাতক ভালো লাগে।

শোরগোল শুনে সাত্তার স্যারের ঘুমটা গেলো ভেঙে। এখনো কাজ হয়নি দেখে মেজাজ সপ্তমে চড়লো, তাই এক রাউন্ড শাস্তি শেষে দায়িত্বটা এবার দেঁড়েল কুদ্দুসকেই দিলেন।

মার্জ সর্ট বা জোড়া বাছাই

কুদ্দুস পড়ায় লবডঙ্কা হলেও কাজের বুদ্ধি প্রখর। বাবা দানু মিঞা সওদাগরের খাতুনগঞ্জের আড়তে বসতে হয়না এখনো, কিন্তু সেখানকার হালচাল ছোটবেলা থেকে দেখে আসাতে এই ধরণের কাজগুলো সহজে করে ফেলতে পারে। কেবল পরীক্ষার খাতাতেই কিছু লিখতে ইচ্ছে করে না। এই নিয়ে ২ বার ফেল করে ক্লাস এইটেই আটকে আছে।

যাহোক, কুদ্দুসের মাথায় এলো, এতো ঝামেলা না করে কাজটাকে ছোট ছোট অংশে ভাগ করে ফেলা যাক। যেমন, আগের উদাহরণের তালিকাটা দেখা যাক। (৬৩, ৫৫, ৬৫, ৫২, ৭১, ৫৬) এই তালিকাটা এক বারে সাজানো কঠিন। তাই কুদ্দুস প্রথমেই এই তালিকাকে দুই ভাগে ভাগ করে ফেললো (৬৩, ৫৫, ৬৫) আর (৫২, ৭১, ৫৬)।

বুদ্ধিটা হলো, এই দুইটা তালিকাকে প্রথমে সাজিয়ে ফেলবে, তার পর এদের দুই তালিকাকে একসাথে জোড়া লাগাবে।
(৬৩, ৫৫, ৬৫) তালিকাটাকে কীভাবে সাজাবে? একই রকম, দুই ভাগে ভাগ করে ফেলা হলো। মাঝের জনকে তো আর কাটা যায় না, তাই তালিকাটা না হয়, (৬৩, ৫৫) আর (৬৫) এভাবে ভাগ হলো।

এবার তো প্রথম তালিকাটা, মানে (৬৩, ৫৫) কে সাজানো সোজা, এদের জায়গা বদল করেই পাওয়া গেলো (৫৫, ৬৩)। তার সাথে (৬৫) এই তালিকাটাকে জোড়া লাগাবো কীভাবে? দুই পাশে দুই তালিকার ছাত্রদের দাঁড় করালো কুদ্দুস। তার পর দুই তালিকার সামনের মাথায় যারা আছে, তাদের তুলনা করলো, যে ছোট, তাকে নেয়া হলো। তাই প্রথমে ৫৫ আর ৬৫ এর তুলনা করে নেয়া হলো ৫৫কে। তার পরে ৬৩ আর ৬৫ এর তুলনা করে ৬৩কে, আর এর পর যেহেতু প্রথম তালিকা শেষ, তাই দ্বিতীয় তালিকার সবাইকে পরপর নিয়ে পাওয়া গেলো (৫৫, ৬৩, ৬৫)।

ব্যাস, শুরুর তালিকাটা গুছানো হয়ে গেলো, পরের ৩ জনের তালিকাটাও একইভাবে গুছিয়ে পাওয়া গেলো (৫২, ৫৬, ৭১)।

এবার কুদ্দুসের হাতে দুটো দল, (৫৫, ৬৩, ৬৫), আর (৫২, ৫৬, ৭১)। এদেরকে জোড়া লাগানোর কাজ শুরু করলো কুদ্দুস।

(৫৫, ৬৩, ৬৫), (৫২, ৫৬, ৭১), [ ] -> (৫৫, ৬৩, ৬৫), (৫৬, ৭১), [৫২] (৫৫ আর ৫২ এর মধ্যে ৫২ ছোট)

(৫৫, ৬৩, ৬৫), (৫৬, ৭১), [৫২] -> (৬৩, ৬৫), (৫৬, ৭১), [৫২, ৫৫] (৫৫ আর ৫৬ এর মধ্যে ৫৫ ছোট)

(৬৩, ৬৫), (৫৬, ৭১), [৫২, ৫৫]->(৬৩, ৬৫), (৭১), [৫২, ৫৫, ৫৬]

(৬৩, ৬৫), (৭১), [৫২, ৫৫, ৫৬] -> (৬৫), (৭১), [৫২, ৫৫, ৫৬,৬৩]

(৬৫), (৭১), [৫২, ৫৫, ৫৬,৬৩]-> ( ), (৭১), [৫২, ৫৫, ৫৬, ৬৩, ৬৫]

( ), (৭১), [৫২, ৫৫, ৫৬,৬৩]-> ( ), ( ), [৫২, ৫৫, ৫৬, ৬৩, ৬৫, ৭১]

ব্যাস, গুছানো শেষ। আর এতে ঝামেলাও কম হলো। ঠিক কতোটা কম, কুদ্দুস নিজেও টের পায়নি, কিন্তু আমরা অংক করে দেখতে পারি, ক জন ছাত্র থাকলে তাদের সাজাতে সময় লাগবে ক x log(ক) সময়, যা আগের দুটো পদ্ধতির চাইতেই অনেক কম।
মার্জ সর্টের বিভিন্ন ধাপের আরেকটি উদাহরণ দেখা যাক নিচের ছবিতে (সূত্রঃ উইকি),



পাদটীকা-

সর্ট বা বাছাইয়ের হাজারো পদ্ধতি আছে, একেক ক্ষেত্রে একেকটি প্রযোজ্য। কম্পিউটার ব্যবহারের প্রতিটি ক্ষণেই যন্ত্রগণক ভেতরে ভেতরে এই সর্টিং করে চলেছে, তাই দ্রুতগতির সর্টিং বা বাছাই পদ্ধতি কম্পিউটার বিজ্ঞানের অত্যন্ত গুরুত্বপূর্ণ বিষয়। সর্টিং সম্পর্কে বিস্তারিত জানতে হলে দেখতে পারেন উইকিপিডিয়াতে।

Tuesday, February 17, 2009

যন্ত্র গণকের যন্তর মন্তর - ২

করিম সাহেবের জাম্বুরা কেনা

করিম সাহেব বাজারে গিয়েছেন জাম্বুরা কিনতে। দোকানী এক গাদা জাম্বুরা সাজিয়ে বসে আছে, সবগুলো দেখতে একই আকারের লাগছে। কিন্তু জাম্বুরা কিনে কিনে চুল পাকানো করিম সাহেব ভালো করেই জানেন, জাম্বুরা যত ভারী হবে, ততো তার স্বাদ ভালো, মজা বেশি।

প্রশ্ন হলো, করিম সাহেব কী করে একগাদা জাম্বুরা থেকে সবচেয়ে ভারীটি বের করবেন।


পাঠ ২

কম্পিউটার প্রোগ্রামিং এ এরকম সমস্যা প্রায়ই আসে, একটা তালিকা থেকে সবচেয়ে বেশি বা কম বা এরকম কিছু একটাকে খুঁজে বের করতে হবে। ধরা যাক, ১০০টা সংখ্যা দেয়া আছে, তার থেকে সবচেয়ে বড় সংখ্যাটা বের করতে হবে।

বিশাল সমস্যা! বেকুব কম্পিউটারকে পুরাটা একবারে দিলে লেজে-গোবরে করে ফেলবে। আসুন, প্রথমে সমস্যাটাকে ছোট করে ফেলি।


১টা যদি সংখ্যা হয়, তাহলে তো আর ঝামেলা নাই। যেটা আছে, সেটাই সবচেয়ে বড়। কাজ শেষ।

২টা যদি সংখ্যা হয়, তাহলে তাদের তুলনা করলেই পাবো কোনটা বড়। সংখ্যা দুইটা ডানহাত ও বামহাত – এই দুই জায়গায় নিয়ে বুঝতে পারি কোনটা বড়। করিম সাহেবের সমস্যায় যদি ফেরত যাই, তাহলে করিম সাহেব দুইটা জাম্বুরা দুই হাতে নিয়ে বুঝতে পারবেন সহজেই কোনটা ভারি।


এখন যদি দুই এর বেশি হয়, ধরা যাক ৩টা, তাহলে? সেটাও সহজ, প্রথমে করিম সাহেব প্রথম দুইটা জাম্বুরা দুই হাতে নিলেন, ধরা যাক ডান হাতেরটা ভারি। তখন বাম হাতেরটা ফেলে ৩য় জাম্বুরাটা বাম হাতে নিলেন, দেখতে চেষ্টা করলেন কোনটা ভারি। ডান হাতে আছে প্রথম দুইটার মধ্যের ভারিটা, আর বাম হাতে অন্যটা, এর মধ্যে যেইটা ভারি হবে, সেটাই ৩টা জাম্বুরার সবচেয়ে ভারিটা।

এই কাজটাকে একটু সাংকেতিক ভাবে এভাবে লেখা যায়, ধরাযাক সংখ্যাগুলো আছে x, y, z এই তিনটা নামে,

যদি X ও Y এর মধ্যে x বড় হয়, তাহলে x ও z এর মধ্যে যেটা বড়, সেটাই বৃহত্তম,

অন্যথায় যদি

X ও Y এর মধ্যে Y বড় হয়, তাহলে y ও z এর মধ্যে যেটা বড়, সেটাই বৃহত্তম।

এই কথাটাই যেকোনো প্রোগ্রামিং ভাষায় লেখা যায়, যেমন ধরুন C ভাষায় লেখা যায় –


if (x>y) { // যদি
if (x>z) largest = x

else largest = z;

} else {

if (y>z) largest = y;

else largest = z;

}

দুর্বোধ্য লাগছে? আসলেই ... এই জিনিষটাকে আরো সংক্ষেপে খুব সহজেই লিখতে পারি এইভাবে -


if x>y largest = x else largest =y;

if z>largest then largest = z;


মানে তিনটা সংখ্যার প্রথম দুইটার মধ্যে বড় যেটা, সেটার সাথে পরেরটার তুলনা করে যেটাকে বড় পাবো, সেটাই সবচেয়ে বড়।

আচ্ছা, ৩টা সংখ্যার মধ্যে না হয় এই দুই লাইনে বের করা গেলো বড় সংখ্যাটি। কিন্তু যদি ৩টার যায়গায় ৩০০ বা ১কোটি সংখ্যা থাকে? করিম সাহেবের কথাই ধরা যাক, ঝুড়িতে যদি ৫০টি জাম্বুরা থাকে, তাহলে কী করবেন তিনি?

মূলনীতিটা কিন্তু একই থাকছে, কাজেই এভাবে আগানো যেতে পারে,

শুরুতে কোনটা ভারী, তা করিম সাহেব জানেননা, তাই তিনি আন্দাজে একটা বেছে নিয়ে ধরলেন সেইটাই সবচেয়ে ভারী। ঐ জাম্বুরাটাকে নিয়ে রাখলেন ডানহাতে।

এবার ঝুড়ি থেকে একটা একটা জাম্বুরা বাম হাতে নেন, আর দেখেন ডান হাতেরটার চেয়ে এই নতুনটা ভারী কি না।

যদি ভারী হয়, তাহলে কথাই নেই, ডান হাতেরটাকে অন্য কোথাও রেখে দিয়ে ডান হাতে পাচার করে দেন বা হাত থেকে নতুন ভারী জাম্বুরাটি।

এভাবে একটা একটা করে ঝুড়ির সবগুলো দেখা হয়ে গেলে সব শেষে করিম সাহেবের ডান হাতে যা থাকছে, সেটাই ঝুড়ির সবচেয়ে ভারী জাম্বুরা।


এবার বেকুব কম্পিউটারকে এরকম ব্যাপার কীভাবে সাংকেতিক উপায়ে বোঝানো যায়, তার একটা রূপরেখা দেখা যাক। ধরাযাক, ১০০টি জাম্বুরা আছে, যাদের নম্বর দেয়া হলো ০ থেকে ৯৯ পর্যন্ত (কম্পিউটার বিজ্ঞানীরা আবার ০ থেকে গোণা শুরু করে)। আর জাম্বুরা গুলোর ওজন ধরা যাক আছে weight[0] থেকে weight[99] এভাবে।

আমাদের কাজ হবে বেকুব কম্পিউটারকে বোঝানো, ১০০টি জিনিষের মধ্যে সবচেয়ে ভারী কোনটা, সেটার ক্রমিক নম্বরটি আমাদের জানানোর কৌশল।

শুরুতে, ধরে নেই প্রথমটি সবচেয়ে ভারী।

heaviest = 0 ; (প্রথমটির ক্রমিক নং হলো ০ )

আর সবচেয়ে ভারী জাম্বুরাটির ওজন আমরা মনে রাখবো max_weight নামে, প্রথমে যেহেতু ধরেছি শুরুর জাম্বুরার ওজন বেশি, তাই সেটার ওজনকেই এখানে মনে রাখি।

max_weight = weight[0];

এবার এক এক করে বাকি গুলোকে পরীক্ষা করি, দেখি এই max_weight এর বেশি পাই কি না

(আমরা একটা একটা করে না লিখে বেকুব কম্পিউটার যেইটা ভালো পারে, সেই পুনরাবৃত্তি তথা লুপের মাধ্যমে করা যায়। সংখ্যা যেহেতু ১০০টি, কাজেই আমাদের অত বার মাপামাপির কাজ করলেই চলবে। এই জন্য কম্পিউটারকে নির্দেশ দেয়া যাক, ১০০ বার সে একটা করে ওজন তুলুক, তার পর দেখুক এইটা আগের চেয়ে ভারী কি না)


for (i = 1; i<100;> এখন কোনটা নিয়ে কাজ করা হচ্ছে, তা i এর মধ্যে রাখবো, আর প্রতি বার লুপের ভিতরের কাজ শেষ হলে ১ করে বাড়াবো। প্রথমটা (০তম) তো দেখেই ফেলেছি, তাই এখন দ্বিতীয়টা, মানে ক্রমিক নং ১থেকে ৯৯ পর্যন্ত বাকি ৯৯টা নিয়ে দেখলেই চলবে)
if (weight[i]>max_weight){ // আগের ওজনদার-তম জাম্বুরার চাইতে এই নতুনটা ভারী কি?
heaviest = i;
max_weight=weight[i]

}
(তাহলে এই নতুনটাই সবচেয়ে ভারী)
(ঐটার ওজনটা মনে রেখে দিলাম)

ব্যস, এই কাজটুকু শেষ ওজন পর্যন্ত করে গেলেই সব শেষে heaviest এর মধ্যে পাবো সবচে ভারী জাম্বুরাটির ক্রমিক নম্বর, আর তার ওজন পাবো max_weight এর মধ্যে।

---

সুতরাং, আজকের পাঠে আমরা দেখতে পেলাম, ভারী হালকা বের করার কাজটা আমরা সুকৌশলে বেকুব কম্পিউটারের ঘাড়ে গছিয়ে দিতে পারি, যাতে করে আমরা নাকে তেল দিয়ে আরামে ঘুমোতে পারি, আর করিম সাহেবও জাম্বুরা কেনায় বিশাল দাওটি মারতে পারেন।

Saturday, February 14, 2009

যন্ত্র গণকের যন্তর মন্তর - ১

ভূমিকা
(সরাসরি চলে যান প্রথম পাঠে)




আমার ছেলেবেলায় বিটিভিতে “বিন্দু থেকে সিন্ধু” নামের একটা অনুষ্ঠান দেখাতো। আশির দশকের কথা ... কম্পিউটার তখন দেশে আছে হাতে গোণা কয়েকটা মাত্র। টিভিতে সেই জাদুর বাক্স দেখে অবাক বিষ্ময়ে তাকিয়ে রইতাম, ভাবতাম কী জাদু জানে এই যন্ত্রটা, কীভাবে করে দেয় সব কাজ।

ঘটনাচক্রে আমার বিদ্যা লাভ করা হয় এই গণক প্রকৌশলেই। প্রোগ্রামিং শেখার শুরুটা আমার কাগজে কলমে, মানে কম্পিউটার কেনার আগেই প্রোগ্রামিং শেখা শুরু করি, মাস খানেক পরে সারা জীবনের বৃত্তির টাকাগুলো ভেঙে কম্পিউটার কেনা হয়। সে এক যুগ আগের কথা।

এই এক যুগ ধরে কম্পিউটার প্রোগ্রামিং শেখার বই এক গাদা দেখলাম। সেই হার্বার্ট শিল্ড থেকে শুরু করে ডেইটেল অ্যান্ড ডেইটেল সহ অনেক লেখকের লেখা সি বা জাভা শেখার বই পড়েছি, পড়িয়েছি। কিন্তু সবগুলো বইয়েরই একটা সাধারন বৈশিষ্ট্য, তা হলো, বইগুলোতে “প্রোগ্রামিং” শেখানো হয়না, যা শেখানো হয় তা হলো সংশ্লিষ্ট ভাষাটির বৈশিষ্ট্য, এবং তা দিয়ে কীভাবে প্রোগ্রাম লেখা যায়।

কম্পিউটার প্রোগ্রামিং এর যে মূল ধারণা, তা সব ভাষার জন্যই প্রায় সমান। কিন্তু দুঃখের বিষয়, বইগুলোতে সেরকম করে মূল ধারণাগুলোর বদলে প্রায়োগিক দিকগুলোই প্রাধান্য পায়।
প্রোগ্রামিং শেখানোটা এক সময় আমার পেশা ছিলো। ছাত্রাবস্থায় ব্যাচে করে সি, জাভা, এসব শেখাতাম। আমার বিদেশে ভর্তির আবেদনের পেছনে যে লাখ টাকার মতো খরচ হয়েছিলো, তার পুরোটাই সেই প্রোগ্রামিং পড়ানোর আয় থেকে যোগান দেয়া। প্রায় দেড়শোর মতো ছাত্রকে একেবারে প্রাথমিক অবস্থার প্রোগ্রামিং শেখাতে গিয়ে আমার মনে হয়েছে, নির্দিষ্ট কোনো ভাষা শেখানোর আগে প্রোগ্রামিং এর মূল ধারণাগুলো, আর কম্পিউটার কীভাবে কাজ করে, তাই যদি শুরুতে শিখিয়ে দেয়া হয়, তাহলে সেই ছাত্রের পক্ষে পরে যে কোনো ভাষাই শেখাটা অনেক অনেক সহজ হয়ে যায়।

বুয়েটে শিক্ষকতার স্বল্প সময়ে প্রোগ্রামিং শেখাবার কোর্স আমি পাইনি, আর পেলেও লাভ হতোনা, কারণ গৎবাঁধা সিলেবাস আমূল পালটে ফেলাটা রীতিমত “অপরাধ” সেখানে। তাই অনেক দিন থেকেই আমার ইচ্ছা, একটা বই লিখবো, যাতে এই ব্যাপারে খুব সহজ করে কথাগুলো বলা যাবে। এই ধারাবাহিক লেখাগুলো এই সিরিজেরই অংশ।

এই লেখাগুলো প্রোগ্রামিং যারা জানেন, তাদের জন্য মামুলি ব্যাপার। এটা মূলত একেবারে কম্পু-কানা নবীস শিক্ষার্থীদের জন্য। তাই ভাষাগত জটিলতা দেখতে পেলেই জানিয়ে দেবেন, আমি ভাষাগুলো আরো সহজ করার চেষ্টা করবো। মিস্তিরি মানুষ হিসাবে ভাষায় দক্ষতা আমার নগন্য, কাজেই দুর্বোধ্য ভাষার ব্যবহার দেখলে সেটাও ধরিয়ে দেবেন।


পাঠ ১

কম্পিউটারের বুদ্ধি কতটুকু? গল্প উপন্যাসে যাই পড়ে থাকুননা কেনো শুরুতেই একটা গোপন কথা ফাঁস করে দেই -- কম্পিউটার একটা চরম নির্বোধ যন্ত্র মাত্র। কম্পিউটার প্রোগ্রামিং শেখার আগেই তাই এই বিষয়টা মেনে নিতে হবে ... টিভি ফ্রিজ বা ওয়াশিং মেশিন, অথবা বাসার ফ্যানটির মতো যেমন বিদ্যুৎ দিয়ে চলে, ঠিক তেমনি কম্পিউটারও বিদ্যুতে চলা একটি যন্ত্র।


তাহলে, কম্পিউটার এতো সব সমস্যার সমাধান কীকরে করে? এর মূলে রয়েছে অ্যালগরিদম, বা গণনা পদ্ধতি। সহজ ভাষায় বলতে গেলে কম্পিউটার সমস্যা সমাধান করতে পারে, তার একমাত্র কারণ হলো, আমরাই সমস্যাগুলোকে ছোট ছোট ভাগে ভেঙে দেই, আর কীভাবে সমাধান করতে হবে, তাও কম্পিউটারকে বাতলে দেই। এই “বাতলে দেয়া বুদ্ধি”টুকু বাদে কম্পিউটার কেবলই সিলিকন-জার্মেনিয়ামের কিছু যন্ত্রাংশের সমাহার।


কম্পিউটার তাহলে কেনো এতো সফল? তার কারণ একটাই, আমাদের বাতলে দেয়া পদ্ধতিতে ছোট ছোট কাজগুলো প্রচন্ড দ্রুতগতিতে কম্পিউটার করতে পারে। হিসাব নিকাশ করার জন্য কম্পিউটারের যে সার্কিট বা বর্তনী রয়েছে, তাতে প্রতি সেকেন্ডে লাখ লাখ থেকে কোটি কোটি ওরকম হিসাব করা যায়। তাই আমাদের বাতলে দেয়া পদ্ধতিতে ছোট ছোট সেই ধাপগুলো কম্পিউটার চোখের নিমেষে করে ফেলে।


কম্পিউটার প্রোগ্রামিং এর মূল কথা হলো সমস্যা সমাধানকে ছোট ছোট ধাপে ভেঙে ফেলা। একেবারে বড় সমস্যা সমাধান হয়তো কঠিন, কিন্তু সমস্যাটাকে সমাধানযোগ্য ছোট ছোট ধাপে ভাগ করে ফেলতে পারলেই কম্পিউটারের মতো নির্বোধ যন্ত্র দিয়ে সেটা সমাধান করা যাবে।

আজ আমরা একটা গাণিতিক সমস্যা দিয়ে এই ব্যাপারটা বোঝার চেষ্টা করবো। ধরা যাক, আপনাকে বলা হলো ১ থেকে ৫ পর্যন্ত সংখ্যাগুলোর যোগফল বের করতে হবে, অর্থাৎ ১+২+৩+৪+৫=? । কাজটা খুবই সহজ, ক্লাস ২ এর বাচ্চাদের দিলে আধা মিনিটেই জবাব দিয়ে দেবে, প্রশ্ন হলো কম্পিউটারকে কীভাবে বোঝাবো সেটা। তার আগে আপনি নিজে ভেবে দেখুন, আপনাকে কাজটা করতে দিলে কীভাবে সেটা করবেন।

খুব আস্তে আস্তে ভাবুন। আপনি নিশ্চয়ই এক বারে ৫টা সংখ্যা যোগ করে বসেননি, তাই না? কাজটা যদি কাগজে কলমে দেয়া হয়, তাহলে আমরা সংখ্যাগুলোকে একটার নিচে আরেকটা লিখে ফেলি। তার পর উপর থেকে শুরু করি, একটা করে সংখ্যা নেই, এপর্যন্ত যা যোগফল ছিলো, তার সাথে সংখ্যাটা যোগ করি, তার পর একই কাজ পরের সংখ্যাটা দিয়ে করি। মুখে মুখে এভাবে চিন্তা করি, "এক আর দুইয়ে তিন, তিন আর তিনে ছয়, ছয় আর চারে দশ, দশ আর পাঁচে পনের", অর্থাৎ আমাদের চিন্তাটা ধাপে ধাপে আগাচ্ছে, প্রতি ধাপে একটা করে সংখ্যা আমরা আগের যোগফলে যোগ করে দিচ্ছি।

হাতে হাতে করার জন্য, ধরা যাক আমরা টেবিলের উপরে ১ থেকে ৫ পর্যন্ত সংখ্যাগুলো রেখেছি, আর ডান হাতে সাময়িক যোগফলগুলো রাখবো। যোগ করার বুদ্ধিটা করলাম এমন, বাঁ হাত দিয়ে টেবিল থেকে একটা সংখ্যা তুলবো, আর সেটাকে ডান হাতে যা ছিলো তার সাথে যোগ করে ডান হাতেই ধরে রাখবো।

যেমন, ১ হতে ৫ পর্যন্ত যোগ করতে হলে, প্রথমে ডান হাতে কিছুই নাই, মানে ০। প্রথম সংখ্যাটি ১। সেটাকে শূন্যের সাথে যোগ করে পেলাম ১।

পরের সংখ্যাটি ২, সেটাকে আমাদের এপর্যন্ত যোগফল ১ এর সাথে সেটাকে যোগ দিলে হয় যোগফল ৩।

পরের সংখ্যাটা ৩, সেটাকে আমাদের এপর্যন্ত যোগফল ৩ এর সাথে যোগ করে পেলাম নতুন ফল ৬।

পরের সংখ্যাটা ৪, সেটাকে আমাদের এপর্যন্ত যোগফল ৬ এর সাথে যোগ করে পেলাম নতুন ফল ১০।

পরের সংখ্যাটা ৫, সেটাকে আমাদের এপর্যন্ত যোগফল ১০ এর সাথে যোগ করে পেলাম নতুন ফল ১৫।

ব্যস, আমাদের যোগফল বের করার কাজটা শেষ, ১ থেকে ৫ এর যোগ ফল দাঁড়ালো ১৫।


উপরের হিসাবের ধাপগুলো দেখলে একটা জিনিষ হয়তো খেয়াল হবে, আমরা একই রকম কাজ (মানে বাঁ হাত দিয়ে টেবিল থেকে সংখ্যা তোলা, আর ডান হাতের সংখ্যাটার সাথে যোগ করার কাজটা) বার বার করছি, কেবল টেবিল থেকে তোলা সংখ্যাটা পালটে যাচ্ছে। আর আমরা এই পুনরাবৃত্তি করছি একটা সীমা পর্যন্ত, মানে ১ থেকে ৫ পর্যন্ত যোগ ফল বের করার ব্যাপার থাকলে টেবিল থেকে ৫ তোলার পরেই থেমে যাচ্ছি। টেবিলের উপরে আরো অনেক সংখ্যা থাকতে পারে, কিন্তু আমরা খেয়াল করে ৫ পর্যন্ত তুলেই থামছি।

এখন দেখা যাক, এই কাজটা বেকুব যন্ত্রগণককে কীভাবে বোঝানো যায় –

ডান হাতে শুরুতে কিছু নাই |

#(প্রথম ধাপ)# ডানহাতে = ০

একেবারে শুরুতে বাম হাতও খালি

#(দ্বিতীয় ধাপ)# বামহাত = ০

আমরা যেটা করবো, তা হলো বাম হাতে একটা একটা সংখ্যা তুলবো, শর্ত ৫ পর্যন্ত তুলার পরে থামবো। প্রতিবারে বাম হাতে আগে যা তুলেছিলাম, তার পরের সংখ্যাটি উঠাবো।

#(তৃতীয় ধাপ)# বামহাত (নতুন মান) = বাম হাতের আগের মান + ১

এইবার ডানহাতে যা ছিলো, তার সাথে বাম হাতেরটা যোগ করে ডান হাতেই রাখবো |

#(চতুর্থ ধাপ)# ডান হাত (নতুন মান) = ডান হাতের পুরানো মান + বাম হাতে যা তুলেছি।

এখন কাজ কি শেষ হয়েছে? মানে বাম হাতে ৫ তুলে ফেলেছি কি? যদি ফেলে থাকি, তাহলে কাজ শেষ, নইলে আবার উপরের ধাপে ফিরে যেতে হবে।

#(পঞ্চম ধাপ)# বাম হাতে যদি ৫ এর চেয়ে ছোট সংখ্যা থাকে, তাহলে কাজ শেষ হয়নি, সুতরাং তৃতীয় ধাপে ফেরত যাই। নইলে কাজ শেষ, পরের ধাপে যাই।

#(ষষ্ঠ ধাপ)# ডান হাতে যা আছে, সেটাই যোগফল, চটপট বলে ফেলি সেটা স্যারকে।

তাহলে ৫ পর্যন্ত যোগ করাটা বোঝা গেলো। ১০০ পর্যন্ত কীভাবে যোগ হবে? একই পদ্ধতি, তাই না? কেবল শর্তের লাইনটিতে ৫ তুলে ফেলেছি কি না তার বদলে আমরা দেখবো ১০০ তুলেছি কি না। সেই একটা সংখ্যা পালটে দিলেই উপরের পদ্ধতিতে ১০০ পর্যন্তও যোগ করা যাবে।

কম্পিউটারের সুবিধা হলো, এই বাম হাত ডান হাতের ব্যাপারটা আর শর্তগুলো একবার বুঝিয়ে দিলে কাজটা সে ৫ পর্যন্ত না, ৫ কোটি পর্যন্তও করতে দিলে অনায়াসে করতে থাকবে। বাচ্চাদের মতো বিস্কুট চকলেটের লোভ দেখিয়ে অংক করতে বসানো লাগবে না।


এই বুদ্ধিটা একটা সি ল্যাঙ্গুয়েজের প্রোগ্রাম আকারে লিখলে কেমন দাঁড়াবে দেখা যাক,

rightHand = 0 (ডান হাত শুরুতে খালি)

leftHand = 0 (শুরুতে বাম হাতও খালি)

do {
leftHand = leftHand + 1 (বাম হাতে আগের সংখ্যাটা যা ছিলো, তার পরেরটা নিলাম। প্রথম বারে কিছুই ছিলোনা, তার সাথে ১ যোগ করে পেলাম বাম হাতে ১)

rightHand = leftHand + rightHand (ডানহাতে আগে যা ছিলো, তার সাথে বামহাতেরটা যোগ করি, তারপর যোগফলটা ডান হাতেই জমা রাখি।)

} while (leftHand <5)>

do–while দিয়ে লেখা অংশটি একটি লুপ বা চক্রকোড। সেটি চলবে ততক্ষণ, যখন while এর পরের শর্তটি সত্য থাকবে। যতক্ষণ ঐ শর্তটি সত্য থাকবে, প্রোগ্রামটি লুপের শেষ মাথায় পৌছে আবার প্রথম অংশে লাফ দিয়ে যাবে।

বাম হাতে ১ থেকে ৫ পর্যন্ত সংখ্যা তুলে ফেলার পর শেষ বারে শর্তটি ভঙ্গ হবে, (কারণ বাম হাতে ৫), তখন এই লুপ আর চলবে না, লুপ শেষ হয়ে পরের অংশের কাজ শুরু হবে।

ব্যস, এটাই হলো কম্পিউটারে সংখ্যা যোগের একটা প্রোগ্রাম।

------

(ব্যাখ্যা ছাড়া সি কোডটি হবে নিচের মতো)

rightHand = 0;
leftHand = 0;

do {
leftHand = leftHand + 1;
rightHand = rightHand + leftHand;
} while (leftHand<5);>