Tuesday, November 2, 2010

അഭാജ്യ സംഖ്യയാണോ എന്നറിയാന്‍ ഒരു C function

തന്നിരിക്കുന്ന അക്കം ഒരു അഭാജ്യ സംഖ്യ (pime number ) ആണോ എന്നറിയാന്‍ ഒരു ചെറിയ C function താഴെ കൊടുക്കുന്നു.

int IsPrime(unsigned int num)
{
int count;
if (num%2 == 0) return (num == 2);
for (count = 3; count*count<=num; count+=2)
{
if ((num%count) == 0) return 0;
}
return 1;
}

ഈ function , തന്നിരിക്കുന്ന സംഖ്യ അഭാജ്യ സംഖ്യ ആണെങ്കില്‍ 1 മടക്കി നല്‍കുന്നു. അഭാജ്യ സംഖ്യ അല്ലെങ്കില്‍ 0 മടക്കി നല്‍കുന്നു. നിരവധി optimaisation വരുത്തിയ ഒരു code ആണ് ഇത്. പ്രോഗ്രാമിന്‍റെ യുക്തികള്‍ പരിശോധിക്കാം
1 ) ഇരട്ട സംഖ്യകളില്‍ 2 മാത്രമാണ് അഭാജ്യ സംഖ്യ. if (num%2 == 0) return (num == 2); എന്ന കോഡ് ഈ യുക്തിയെ ഉപയോഗപ്പെടുത്തിയിരിക്കുന്നു. രണ്ടു അല്ലാത്ത ഇരട്ടസംഖ്യ ആണ് തന്നിരിക്കുന്നതെങ്കില്‍, വേറെ ഒന്നും നോക്കേണ്ടതില്ല, സംഖ്യ ഭാജ്യ സംഖ്യ ആണെന്ന് നിസ്സംശയം പറയാം.
2 ) ഇരട്ട സംഖ്യ അല്ലെങ്കില്‍ തന്നിരിക്കുന്ന സംഖ്യ,
a ) 3 , 5 , 7 , 9 തുടങ്ങിയ ഒറ്റ സംഖ്യകളുടെ ഗുണിതം ആണോ എന്ന് പരിശോധിക്കുക, ആണെങ്കില്‍ അത് ഭാജ്യ സംഖ്യ ആണെന്ന് ഉറപ്പിക്കാം. ഇരട്ട സംഖ്യകളുടെ ഗുണിതം എന്നും ഇരട്ട സംഖ്യ തന്നെ ആയിരിക്കും എന്നതിനാല്‍ 2 , 4 , 6 , 8 തുടങ്ങിയ ഇരട്ട സംഖ്യകളുടെ ഗുണിതം ആണോ എന്ന് പരിശോധിക്കേണ്ടതില്ല. (ഇരട്ട സംഖ്യകളുടെ വിധി നമ്മള്‍ ( 1 ) ല്‍ തീരുമാനിച്ചിട്ടുണ്ട്) .
b ) സംഖ്യയുടെ വര്‍ഗമൂലം (square root ) വരെയുള്ള അക്കങ്ങളുടെ ഗുണിതം ആണോ എന്ന് പരിശോധിച്ചാല്‍ മതി. അത് വരെയുള്ള ഒരു അക്കത്തിന്‍റെയും ഗുണിതം അല്ലെങ്കില്‍ നിസ്സംശയം പറയാം, സംഖ്യ അഭാജ്യ സംഖ്യ ആണ്.

സാധാരണയായി കാണാറുള്ള പ്രോഗ്രാമുകളില്‍ മുകളിലുള്ള യുക്തികള്‍ കാണാറില്ലാത്തതിനാല്‍ അവ വളരെ അധികം സമയം എടുക്കും, പ്രത്യേകിച്ച് വലിയ സംഖ്യകള്‍ പരിശോധിക്കുമ്പോള്‍.
നിങ്ങളുടെ ആടുത്ത് സാധാരണ യുക്തിയിലുള്ള ഒരു C function ഉണ്ടെങ്കില്‍, അതില്‍ 15485863 ഒരു അഭാജ്യ സംഖ്യ ആണോ എന്ന് പരിശോധിക്കൂ. പിന്നീട് ഈ പ്രോഗ്രാം ഉപയോഗിച്ച് ഉത്തരത്തിന് എടുക്കുന്ന സമയം താരതമ്യപെടുത്തി നോക്കൂ.

Monday, August 23, 2010

അധിവര്‍ഷം കാണാന്‍ ഒരു C function

ഒരു വര്‍ഷം കിട്ടിയാല്‍ അത് അധിവര്‍ഷം(leap year) ആണോ അല്ലയോ എന്ന് നോക്കാനുള്ള ഒരു കൊച്ചു C function.

int Isleap(unsigned int year)
{
/*Return 1, if it is a leap year. return 0 if it is not a leap year*/
return ( !(year % 4) && ((year % 100) || !(year % 400)));
}

ഈ function ഉപയോഗിച്ച് നിരവധി ഉപയോഗങ്ങളുണ്ട്. ഉദാഹരണമായി, 1990 എന്ന വര്‍ഷത്തിലെ ദിവസങ്ങളുടെ എണ്ണം കാണണം എന്നിരിക്കട്ടെ, താഴെ കൊടുത്തിരിക്കുന്ന ഒരൊറ്റ ലൈന്‍ കോഡ് മതിയാവും.

noofdays = 365 + Isleap(1990);

പ്രോഗ്രാമിലെ യുക്തി:

താഴെ പറയുന്ന വസ്തുതകള്‍ പരിഗണിക്കുക.

1) ഒരു വര്‍ഷത്തെ 4 കൊണ്ട് ഹരിക്കാന്‍ കഴിയുമെങ്കില്‍, അത് 100 കൊണ്ട് ഹരിക്കാന്‍ പറ്റാതിരിക്കുകയോ 400 കൊണ്ട് ഹരിക്കാന്‍ പറ്റുകയോ ചെയ്യുകയാണെങ്കില്‍ അത് അധിവര്‍ഷം ആണ്.
2) ഒന്നാമത്തെ വിഭാഗത്തില്‍ പെടാത്തതൊന്നും അധിവര്‍ഷം അല്ല.
3) ( divisor % divident) = 0 , ആണെങ്കില്‍ divident devisorഇന്‍റെ ഒരു ഘടകം(factor) ആണ്.
4) expression1 അല്ലെങ്കില്‍ expression2, ഇവയില്‍ ഏതെങ്കിലും ഒന്ന് പൂജ്യം ആയാല്‍ (expression1) && (expression2) ഉം പൂജ്യം ആയിരിക്കും.

ഇനി പ്രോഗ്രാമിലേക്ക്..

ചുവട് 1:
!(year % 4) : year എന്നത് 4 കൊണ്ട് ഹരിക്കാന്‍ പറ്റുമെങ്കില്‍ ഇത് 1 ആണ്. ഇല്ലെങ്കില്‍ ഇത് 0 ആണ്. വസ്തുത 4-ഇല്‍ പറഞ്ഞ expression1 ആണിത്.

ചുവട് 2:
ചുവട് 1 ലെ ഉത്തരം പൂജ്യം ആണെങ്കില്‍ ഈ ചുവടിനു പ്രസക്തി ഇല്ല(വസ്തുത 4 നോക്കുക). അതായത്, 4 കൊണ്ട് ഹരിക്കാന്‍ പറ്റുമെങ്കില്‍ മാത്രം ഈ ചുവട് ചെയ്‌താല്‍ മതി.
(year % 100) || !(year % 400): 100 കൊണ്ട് ഹരിക്കാന്‍ പറ്റാതിരിക്കുകയോ 400 കൊണ്ട് ഹരിക്കാന്‍ പറ്റുകയോ ആണെങ്കില്‍ ഇത് 1 ആണ്. 4 കൊണ്ട് ഹരിക്കാന്‍ പറ്റുന്നതാണ് എന്ന് നേരത്തെ ഉറപ്പുള്ള സ്ഥിതിക്ക്, വസ്തുത 1 പ്രകാരം ഇത് അധിവര്‍ഷം ആയി കണക്കാക്കാം.

ഇനിയും ലളിതമായ വഴികള്‍ കണ്ടേക്കാം. പങ്കു വെക്കുമല്ലോ..

Wednesday, March 31, 2010

Tired of local spammers?

It was not so long back; I received a forwarded email to my gmail inbox from a stranger. I pressed archive button, thinking that he is an innocent don't care guy and also the mail was no so boring one. To be fair, I felt nothing annoying. Unfortunately, that was just a start. I used to receive forward mail daily from that guy, all with huge sized attachments in it. He was forwarding mails like he had promised to send atleast one mail of 2-3 MB attachments in it. I tried to recollect who he is. Is he an old friend of mine? or else how he got my email id? I started scanning the huge "To" and "cc" list of his mail. There were many friends of mine in that list. I couldn't guess any relation with him since he had many of my friends in different fields. If there were only my class mates/ batch mates, I could have guessed he is my college mate I lost from my memory. But what will I do when I know there are friends of me from work places too?
I had nothing to do, except just deleting those mails. When I asked my friends who was in the cc list, they were also in the same position like me! I was ok with it untill I received a mail from him which contains pictures of a very ugly dead bodies and pool of blood in it. I was fed up when I received more of it. I politely replied to that person asking to remove me from his mailing list. The result? No, he didn't remove me from his mailing list, instead there was a flammable reply from him, abusive and he continued his work. What next? I didn't go behind him, here is what I did.


Opened my gmail inbox
Clicked on "create a filter" ("search web" button)
Filled in "From" text box with my spammer's mail id.
Clicked on "Next step" button
Ticked "Forward it to" check box and gave my spammer's mail id to forward.
Ticked on "Delete it" check box
Clicked on "Create filter" button.

Done!!

What it did?
Whenever my spammer sends a mail, gmail will move it to thrash folder and automatically forward it back to him.
Whats more intresting? The "backwarded" message will not have my mail id as sender, instead it will be his address itself!! May be you too can try this, if you are a victim!