Monday, February 26, 2024

সি শেখানোর করুণ কাহিনী

 অনেক বয়স হয়ে গেল বুঝলেন তো ,একসময় কারোর বয়স বত্রিশ শুনলেই অবজ্ঞায় ঠোঁট বেঁকে যেত ,বুড়ো মাল ,ঘাটের মরা এইসব ভাবতাম ,এড়িয়ে চলতাম বলা চলে ,এখন নিজেই চল্লিশ ,চুল কম পাকলো ,দাড়ি বেশি পেকে গেলো ,সেই দেখে আবার এক বাচ্চা ছেলে দাদু বলে ডেকেছিল 


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


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


হেনস্থার প্রসঙ্গে আসি ,ছাত্রী সি প্রোগ্রামিং এ ইনপুট এ একটি বাক্য নিতে পারছে না,খুব উৎসাহ নিয়ে scanf বোঝাতে গেলাম,দেখলাম নিজের ও হলো না ,কেন ,কারণ ডব্লিউ বিউটি তে শেখানো হয় নি ,scanf দিয়ে যদি ইনপুট নেন ,ইউজার যদি ইনপুট এ অতিরিক্ত ব্ল্যান্ক স্পেস  টাইপ করে বা নিউলাইন ক্যারেক্টার টাইপ করে scanf ইনপুট নেবেই না ,ছাত্রী কে আরেকটা কাজ দিয়ে নিজে একটু গুগুল করে নিলাম ,দেখলাম সমস্যার সমাধান আছে ,কপি করে দিলাম 


#include <stdio.h> 

  


int main() 

    char sen[100]; 

    scanf("%[^\n]s", sen  ); 

    printf("Output : %s", sen); 

    return 0; 


এই প্রোগ্রামটি একটা সেন্টেন্স কে ইনপুট হিসেবে নিতে পারে,ছাত্রীকে দেখিয়ে বেশ একটা কের্দানি  করেছি কি করিনি ,ছাত্রী বলে আরে  এতো প্রথম সমস্যা ,মূল সমস্যার ছোট একটি অংশ মাত্র 


আমি ঘাবড়ে গেলাম,বুজলাম আরো হেনস্থা আছে কপালে ,বললাম কি সমস্যা আছে বলো ,মনে মনে ভাবছি বেশি জটিল যেন না হয় ভগবান ,এই মাসের মাইনে  বাকি 



বলে এইভাবে একটা কালেকশন অফ স্ট্রিং নিতে হবে ইনপুট হিসেবে ,স্ট্রিং মানে জানেন তো ,ধরুন আপনার নাম sourav ,s  একটা ক্যারেক্টার ,এরকম  একাধিক ক্যারেক্টার কে হয় একটা স্ট্রিং ,মানে sourav একটা string ,ক্যারেক্টার মানে যা ইচ্ছা হতে পারে ,নাম্বার ও হতে পারে ,সেই হিসেবে ১০০ ও একটা স্ট্রিং হতে পারে,তবে স্ট্রিং ডবল কোটেশনে ঢাকা থাকবে ,"১০০" বা "সৌরভ",ক্যারেক্টার হলে সিঙ্গল কোটেশনে ঢাকা থাকবে 'স',এই হলো গিয়ে সি প্রোগ্রামিং এর নিয়ম কানুন 


বললাম সে ঠিক আছে একটা কালেকশন অফ স্ট্রিং নিতে হবে ,তারপর ,উপরের প্রোগ্রামটি তো একটা কালেকশন অফ স্ট্রিং বা একটি বাক্যকে ইনপুট হিসেবে নিয়ে একটি স্ট্রিং ভ্যারিয়েবল এ স্টোর  করতে পারে তাই না ,তার মানে প্রব্লেম তো সল্ভড 


সে বিরক্ত হয়ে বলে আরে নানা একটা ভ্যারিয়েবল নয় একটা এরে তে স্টোর করতে হবে ,তারপর শব্দগুলো সর্টিং করতে হবে ,সর্টিং মানে কি ,না আলফাবেট এর ক্রোম অনুযায়ী আগে পরে বসবে 


একটা উদাহরণ দি ইন্টারনেট থেকে কপি করে 


ধরুন ইনপুট এসেছে 


Input: arr[] = {“geeks”, “for”, “geeksforgeeks”} 

Output: 

for

geeks

geeksforgeeks


বুঝতেই পারছেন প্রতিটা শব্দের সঙ্গে অন্য শব্দগুলোর তুলনা বলে ,এরকম তুলনার একটা নাম আছে ,lexicographical তুলনা ,এখানে প্রতিটা স্ট্রিং এর প্রতিটা অক্ষর আরেকটি স্ট্রিং এর সিম পজিশনে থাকা অক্ষরের সঙ্গে তুলনা হয় 


ইন্টারনেট থেকে কপি করে একটা প্রোগ্রাম দেখাই 


#include <stdio.h> 

  

void compareStrings(char* s1, char* s2) 

    int i; 

    // comparing each character 

    for (i = 0; s1[i] != '\0' || s2[i] != '\0'; i++) { 

        if (s1[i] > s2[i]) { 

            printf("String 1 is lexicographically greater "

                   "than string 2"); 

            return; 

        } 

        else if (s2[i] > s1[i]) { 

            printf("String 2 is lexicographically greater "

                   "than string 1"); 

            return; 

        } 

    } 

    // comparing length of two strings 

    if (s1[i] != '\0') { 

        printf("String 1 is lexicographically greater than "

               "string 2"); 

    } 

    else if (s2[i] != '\0') { 

        printf("String 2 is lexicographically greater than "

               "string 1"); 

    } 

    else { 

        printf("Both strings are lexicographically equal"); 

    } 

int main() 

  

    // declaring two strings 

    char s1[20] = "help"; 

    char s2[20] = "held"; 

  

    // function call 

    compareStrings(s1, s2); 

    return 0; 

}



এই প্রোগ্রামটি কি করতে পারে ,দুটো স্ট্রিং এর মধ্যে কম্পেয়ার করতে পারে ,কিন্তু এতে আমার কাজ শেষ হচ্ছে না ,আমাকে পুরো বাক্যের প্রতিটা শব্দের বা স্ট্রিং এর সঙ্গে ওপর প্রতিটি বাক্যের বা স্ট্রিং এর এরকম কম্পারিসন করতে হইবে 


এই প্রোগ্রামটি কি ভাবে কাজ করছে সেটাও নেট থেকে কপি করে লিখছি 


Iterate over both the strings using a for-loop.

Compare each character of the two strings till an unmatched character is found.

For the unmatched character at position i, if s1[i] < s2[i], s1 is lexicographically smaller string.

Otherwise, s2 is the lexicographically smaller string.

If no unmatched character is found, compare the length of both strings.

The longer string is lexicographically smaller.


সমস্যার ছোট একটি অংশ সমাধান হলো 


এবার এই অংশ টিকে ব্যবহার করতে হবে এমন একটি প্রোগ্রাম এ যেখানে প্রোগ্রাম প্রতিটা স্ট্রিং এর মধ্যে এই উপরের প্রোগ্রামটি চালাবে 


আবার গুগুল করে চুরি করে লিখে দিলাম একটা ,নির্লজ্জের মতো লাইন বই লাইন কপি বলাই বাহুল্য 


#include<stdio.h>

#include<string.h>

int main()

{

   char str[5][50],temp[50];

   int i,j;


   printf("Enter 5 Words:\n");


   for(i=0;i<5;i++)

   scanf("%s[^\n]",str[i]);


   for(i=0;i<4;i++)

   {

     for(j=i+1;j<5;j++)

     {

       if(strcmp(str[i],str[j])>0)

       {

         strcpy(temp,str[i]); 

         strcpy(str[i],str[j]);

         strcpy(str[j],temp);

       }

     }

   }

   printf("\nIn lexicographical order: \n");


   for(i=0;i<5;i++)

   puts(str[i]);


   return 0;

}


কাজ হচ্ছে ,কিন্তু ছাত্রী খুশি নয় ,বলে ম্যাডাম মানা  করেছেন এরকম স্ট্রিং লাইব্রেরি ব্যবহার করতে ,নিজে ফাঙ্কশন বানাতে হবে 

মাথায় বাজ পড়লো ,বুজলাম দিন খারাপ ,এতো বড় মাপের প্রোগ্রামার কবে হলাম আমি সি প্রোগ্রামিং এর ইন বিল্ট ফাঙ্কশন রিপ্লেস করে নিজের বানাবো 


যায় হোক আবার গুগুল  থেকে চুরি করলাম 


এদিক ওদিক থেকে চুরি করে ঘন্ট টাইপের বানালাম একটা 


int my_strcmp(const char *a, const char *b)

{

    while (*a && *a == *b) { ++a; ++b; }

    return (int)(unsigned char)(*a) - (int)(unsigned char)(*b);

}


যাতে strcmp ফাঙ্কশন টা অন্তত রিপ্লেস হলো,strcmp  না ব্যবহার করে এখন নাহয় my_strcmp ব্যবহার করবো 


ছাত্রী এবার বললো সি তে ইন বিল্ট ফাঙ্কশন পাল্টে (গুগুল থেকে চুরি ) যে ফাঙ্কশন তা লেখা হয়েছে বুঝতে পারছে না 


আবার মাথায় বাজ পড়লো ,গুগুল খুঁজতে আরম্ভ করলাম একই জিনিস আর একটু সহজ ভাবে (পড়তে হবে পয়েন্টার এর জঙ্গল না ইউজ করে বা রেকারসন ব্যবহার না করে)কেউ করেছে কি না 


অনেক খুঁজে মিলিয়ে মিশিয়ে করলাম একটা 


এরকম দাঁড়ালো জিনিসটা 



#include <stdio.h> 

#include<string.h>


  

/*int my_strcmp(const char *a, const char *b)

{

    while (*a && *a == *b) { ++a; ++b; }

    return (int)(unsigned char)(*a) - (int)(unsigned char)(*b);

}*/


int compareStrings(const char *s1, const char *s2) 

    int i; 

    // comparing each character 

    for (i = 0; s1[i] != '\0' || s2[i] != '\0'; i++) { 

        if (s1[i] > s2[i]) { 

            return (int)(unsigned char)(*s1) - (int)(unsigned char)(*s2);

            //printf("String 1 is lexicographically greater ""than string 2"); 

            //return; 

        } 

        else if (s2[i] > s1[i]) { 

            //printf("String 2 is lexicographically greater ""than string 1"); 

            //return; 

            return (int)(unsigned char)(*s1) - (int)(unsigned char)(*s2);

        } 

    } 

    // comparing length of two strings 

    if (s1[i] != '\0') { 

        return (int)(unsigned char)(*s1) - (int)(unsigned char)(*s2);

    } 

    else if (s2[i] != '\0') { 

        return (int)(unsigned char)(*s1) - (int)(unsigned char)(*s2);

    } 

    else { 

        return 0;

    } 


int main()

{

   char str[5][50],temp[50];

   int i,j;


   printf("Enter 5 Words:\n");


   for(i=0;i<5;i++)

   scanf("%s[^\n]",str[i]);


   for(i=0;i<4;i++)

   {

     for(j=i+1;j<5;j++)

     {

       if(compareStrings(str[i],str[j])>0)

       {

         strcpy(temp,str[i]); 

         strcpy(str[i],str[j]);

         strcpy(str[j],temp);

       }

     }

   }

   printf("\In lexicographical order: \n");


   for(i=0;i<5;i++)

   puts(str[i]);


   return 0;

}


তখন ও ছাত্রীর মন ভরেনি ,বুঝে গেলাম এই মরণাত্মক সংগ্রাম আমার পোষাবে না ,অদ্যই শেষ রজনী 


মাইনের আশা আর নেই ,এতো খাটনি (মানে চুরি আর চুরির মাল এসেম্বলি)তো বাড়ির লোক বুজবে না ,ছাত্রী বলবে ইস্সে না হইবা ,মা বলবে মাস্টার ফোটো 


তবে শিক্ষকের সম্মান ,কঠিন ব্যাপার ছিল সেই সময় 


গভীরভাবে বললাম এতে কি খুশি হবেন তোমার ম্যাডাম 


ছাত্রী বললো আচ্ছা strcpy তা প্রতিস্থাপন করা যায় না,তাহলে string.h  লাইব্রেরি ই আর ইম্পোর্ট করতে হবে না 


বললাম দেখছি দাড়াও ,দশ বছর হয়ে গেলো ,সেই দেখা আজ থামেনি ,বুঝে গেছি আমি ভালো প্রোগ্রামার হতে পারবো না 


কয়েকদিন আগে আমার এক বেড়ে পাকা বন্ধুর সঙ্গে এই নিয়ে কথা হচ্ছিলো 


ও বললো আরে এ তো পাইথন এ হেবি সোজা 


এক লাইন জাস্ট 


def sort_words(words):

    return ' '.join(sorted(words.split(), key=str.casefold))



# commands used in solution video for reference

if __name__ == '__main__':

    print(sort_words('banana ORANGE apple')) 




এইটাই হলো সেই ম্যাজিক এক লাইন 


return ' '.join(sorted(words.split(), key=str.casefold))


তাও আমি আশা হারাইনি ,নিশ্চয় সি প্রোগ্রামিং করে একদিন আমি পুন্য অর্জন করবো 



No comments:

Post a Comment