পোস্টটি পড়া হয়েছে 2,422 বার
UVa 10931 Parity Solution in Bengali

অনলাইন জাজ সিরিজ – ৬ (Test case, EOF)

কনটেস্টে বা অনলাইন জাজে প্রবলেম সলভ করার সময় ২-৩ রকম ভাবে ইনপুট নেয়ার দরকার হতে পারে। সেগুলো নিয়ে আজ দেখব।

টেস্ট কেসের সংখ্যা ইনপুট নেয়া (Given the number of Test Cases)
কখনো কখনো প্রবলেম ডেস্ক্রিপশনে বলে দেয়া থাকে যে জাজের ইনপুট ফাইলে কতগুলো টেস্ট কেস থাকবে। যদি সংখ্যাটা হয় T তার মানে হচ্ছে জাজের পিসিতে input.txt নামের হয়ত একটা ফাইল আছে সেই ফাইলের ভিতরে T সংখ্যক ইনপুট সেট আছে। যা দিয়ে জাজ পিসি আমাদের প্রোগ্রামটাকে চেক করে দেখবে।

এক্ষেত্রে আমাদেরকে প্রথমেই এই টেস্ট কেসের সংখ্যাটা ইনপুট নিতে হয়। কারণ সাধারণত input.txt টাইপের ফাইলগুলোর একদম প্রথম লাইনেই বলা থাকে এই ফাইলে ঠিক কত সেট ইনপুট ডেটা রাখা আছে। এটা ইনপুট নেয়ার পরে আমাদের কাজ হয় একটা লুপ ঘুরিয়ে T সংখ্যক বার ফাইল থেকে মেইন ইনপুট ডেটা সেট ইনপুট নেয়া, সেগুলোকে প্রসেস করে আউটপুট দেখানো। উদাহরণ হিসেবে LightOJ 1000 প্রবলেমের কোডটা দেখানো যায়।

লক্ষ্য কর, যদি আমাদেরকে বলা হত যে ইনপুট ফাইলে একটাই ইনপুট থাকবে। তাহলে কিন্তু আমরা টেস্ট কেসের সংখ্যা ইনপুট নিতাম না। লুপটাও চালাতাম না। কোডে শুধু ৩, ৪ ও ৫ নাম্বার লাইনগুলোই লিখতাম।

End of File বা EOF পর্যন্ত ইনপুট নেয়া
কখনো কখনো প্রবলেমে টেস্ট কেস ইনপুট নেয়ার কথা বলা থাকে না। আবার কখনো শুধু বলা থাকে “ইনপুট ফাইলের শেষ পর্যন্ত ইনপুট নাও”  বা “যতক্ষন না পর্যন্ত ইনপুট ফাইল শেষ হচ্ছে ইনপুট নিতে থাক”। উভয় ক্ষেত্রেই আমাদেরকে কাজ করতে হবে End of File (EOF) নিয়ে।

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

উপরের কোড ব্লক (EOF 1.1) এর প্রথম লাইনে while loop এর ( ) এর ভিতরে ইনপুট নেয়া হচ্ছে। () এর ভিতরে while loop এর কন্ডিশন লিখা হয়। এই কন্ডিশনটি সত্য হলে লুপের ভিতরের কাজটি execute হয়, নচেৎ loop টি break করে। এখানে কন্ডিশন দেখা যাচ্ছে (scanf(“%d %d”, &a, &b) ! = EOF)। প্রথমে দুইটা পূর্ণসংখ্যা ইনপুট নেয়া হচ্ছে। এরপর চেক করা হচ্ছে “কার্সর কি ফাইলের শেষে এখনো পৌঁছায় নাই”? যদি এটি ফাইলের শেষ প্রান্তে না পৌঁছে থাকে  তাহলে কন্ডিশনটি হবে true. তারমানে এখনো ইনপুট নেয়ার মত আরো ডেটা ফাইলে আছে। লুপের ( ) এর ভিতরের কন্ডিশন সত্য, অতএব লুপের ভিতরে ঢোকা হোক। কিন্তু যদি কার্সরটি সত্যি সত্যি ফাইলের একদম শেষ প্রান্তে (EOF) পৌঁছে গিয়েই থাকে তাহলে কন্ডিশনটি হবে false. তখন লুপের ভিতরে আর ঢোকা হবে না। Loop-টি break করবে এবং প্রোগ্রামটি terminated হবে।

 

উপরিউক্ত কোডের (EOF: 1.2) প্রথম লাইনেও মূলত EOF পর্যন্তই ইনপুট নেয়া হবে। কিন্তু লেখার পদ্ধতিটা ভিন্ন। আমরা জানি printf() ও scanf() ফাংশনগুলোর return type হচ্ছে integer. কিন্তু কখনো আমরা এই ফাংশনগুলোর থেকে রিটার্ন করা ভ্যালুগুলো নিয়ে কাজ করি না। এই scanf() ফাংশনের রিটার্ন করা ভ্যালু দিয়েই আমরা EOF implement করতে পারি। এই ফাংশন দুটির return type নিয়ে জানতে পারবে এখান থেকে

যেহেতু scanf() ফাংশন রিটার্ন করে যে এটি কতগুলো ডেটা সফল ভাবে ইনপুট নিতে পেরেছে তাই int ret = scanf(“%d %d”, &a, &b); লিখলে ret এর মান পাওয়া যাবে ২ (যদি সত্যিই দুটি ইনপুট দেয়া হয়)। আর লুপের condition checking part এ এই চেকটি রাখা হয়েছে (scanf(“%d %d”, &a, &b)==2) অর্থাৎ এই scanf() ফাংশন এর রিটার্ন করা ভ্যালুটা ২ কিনা? যদি ২ হয় তার মানে ২টি ইনপুট নেয়া হয়েছে, সুতরাং এই দুটিকে প্রসেস করে আউটপুট দেখাতে হবে। তাই কন্ডিশন সত্য হওয়ায় লুপে ঢোকা হবে এবং কাজগুলো করা হবে। কিন্তু যদি কার্সর একদম ফাইলের শেষ প্রান্তে থাকে, যেখানে আসলে ইনপুট নেয়ার জন্য দুটি int টাইপের ডেটা নাই। তাহলে ফাংশনটি রিটার্ন করবে শূন্য। যেহেতু শূন্য ২ এর সমান না, তাই কন্ডিশন মিথ্যা। তার মানে মান পাওয়া যায় নাই, so লুপের ভিতরেও ঢোকার দরকার নাই। লুপটা break হয়ে যাবে।

এই কোডের অংশটি (EOF 1.3) আসলে আগেরটার (EOF 1.2) মতই। আগেরটায় চেক করা হয়েছিল ফাংশনের রিটার্ন করা ভ্যালু ২ কিনা। কিন্তু এখানে শুধু চেক করা হচ্ছে রিটার্ন করা ভ্যালু শূন্য থেকে বড় কিনা?

আমরা জানি IF বা Loop এর condition checking part এ শূন্য পাওয়া গেলে কন্ডিশন মিথ্যা হয়। আর ‘অশূন্য’ কোন কিছু পাওয়া গেলে কন্ডিশন সত্য হয়। সেই হিসেবে যদি এই কোড ফাইল থেকে ২ টি সংখ্যা read করতে পারে তাহলে রিটার্ন করবে ২ যা অশূন্য। তাই লুপের ভিতর ঢোকা হবে। যদি ইনপুট নিতে না পারে তাহলে scanf() ফাংশনটি রিটার্ন করবে শূন্য। সেক্ষেত্রে লুপের ভিতরে ঢুকবে না। Loop-টি break হয়ে যাবে।

মোটামুটি উপরের ৩ ভাবে EOF পর্যন্ত ইনপুট নেয়া যায়। নিজেরা কোড কর একটু ঘাটাঘাটি কর। আশা করি আরো ক্লিয়ার হবা। Windows পিসিতে কোড রান করে কনসোলে ইনপুট হিসেবে F6 বাটন প্রেস করলে ^Z ইনপুট হবে। এটাই তোমার কোডে EOF বা ফাইল শেষ এর কমান্ড। Enter বাটন প্রেস করলে যদি তোমার প্রোগ্রাম close হয়ে যায় তাহলে বুঝবে EOF এর জন্য তোমার কোড কাজ করেছে।

Test Case বা EOF কোনটাই না
Codeforces এর প্রবলেমগুলোতে সাধারণত টেস্ট কেস ইনপুট নিয়ে লুপ ঘুরিয়ে সব কাজ লুপের ভিতরে করা লাগে না। সম্ভবত তাদের জাজ পিসি আমাদের সাবমিট করা কোডগুলোকে চেক করার জন্য প্রতিবার রান করে। তাই সেখানে কোড করার সময় সিঙ্গেল একটা ইনপুট সেটের জন্য কোড করলেই হয়। (Codeforces এ কোড জাজ করার সময় আসলেই প্রতিবার কোড রান করা হয় কিনা আমি নিশ্চিত না। অন্য কোন ভাল প্রসেসও থাকতে পারে।)

তাই কোন জাজ যদি EOF বা টেস্ট কেসের কথা উল্লেখ না করে আর তাদের প্রসেসটা জানা থাকে সেক্ষেত্রে একটা ইনপুট সেটের জন্যও কোড লিখে সাবমিট করা যায়। যদিও অনেক সিনিয়র প্রবলেম সলভারদের দেখেছি সতর্কতামূলক ভাবে এসব ক্ষেত্রেও EOF হিসেবেই কোড করেন।

সিম্পল কিছু কথাবার্তা বললে বলতে দেখি লেখাটা প্রায় হাজার খানেক শব্দের উপন্যাস হয়ে গেছে। :'( দুঃখিত, যে আমি অল্প কথায় পুরো বিষয় বোঝানোর মত এক্সপার্ট এখনো হই নি। যখন হব তখন পোস্ট এডিট করে ছোট করে দিব।

আর সকলের পরামর্শ পেলে তো পোয়া বারো!!! 🙂

Comments

comments

1 thought on “অনলাইন জাজ সিরিজ – ৬ (Test case, EOF)

Leave a Reply

Your email address will not be published. Required fields are marked *