#include <stdio.h>
#include <ctype.h>
#include <string.h>
int commonnum (char s1[20],char s2[20]);
int main()
{
int sp=0,i,m=6,x,j=0,q;
char s[]={'f','l','a','m','e','s'},fate,change_fate,name1[20],name2[20];
printf("\n%s",s);
start:
printf("\nenter a names");
scanf("%s",name1);
printf("\nenter second name");
scanf("%s",name2);
//printf("enter the commons number");
//scanf("%d",&x);
x=commonnum(name1,name2);
if (x==0)
{
printf("\naaaa no cheating!!!!");
goto start;
}
printf("\n%d",x);
y:
for(i=0;i
{if(s[i]!='!')
{
if(j==x-1)
{
s[i]='!';
j=-1;
sp++;
}
j++;
}
//printf("\n %s",s);
if(i==m-1)
goto y;
if(sp==5)
{
for(q=0;s[q]!='\0';q++)
if(s[q]!='!')
{printf("\n%c",fate=toupper(s[q]));
switch(fate)
{case 'F':printf("\nFRIEND! not bad can try later;");break;
case 'L':printf("\nLOVER!!! u r the luckiest being on earth");break;
case 'A':printf("AFFECTION! end up u r life making difference b/w love and affection");break;
case 'M':printf("\nMARRIAGE!!! a famous saying \"wife is a knife that cuts u r life\"");break;
case 'S':printf("SISTER!!!! i pity you ;)");break;
case 'E':printf("ENEMIES lets wage a war!!!!!!!!!");
}}
break;}
}
getchar();
printf ("Wanna change u r love ?\n");
change_fate=getchar();
if(change_fate=='y')
goto start;
return 0;}
int commonnum(char name1[],char name2[])
{int i,j,count=0;
char temps[20];
if(strlen(name2)>strlen(name1))
{ strcpy(temps,name1);
strcpy(name1,name2);
strcpy(name2,temps);
}
for(i=0;name2[i]!='\0';i++)
for(j=0;name1[j]!='\0';j++)
if(name2[i]==name1[j])
count++;
return strlen(name1)+strlen(name2)-2*count;
}
Refactorings
No refactoring yet !
Ants
August 11, 2009, August 11, 2009 23:58, permalink
I've got a couple of questions about your code...
Line 26: Where is the rest of the for statement? (I'm going to assume that you meant 'for(i=0;i<6;i++)')
Lines 8,12,14: What happens when somebody enters more than 19 characters for a name?
Line 10: What happens if the user presses 'y' down at line 60-61? (Hint: Look closely at s[], j, and sp.)
Lines 19-23: Why is name1=="dean" and name2="edna" cheating?
Lines 19-23: What happens when name1=="dan" and name2="anna" ? (e.g. commonnum() returns a negative number)
Line 42: How are you guaranteed that the s[q] will eventually hit a '\0' if there isn't a '\0' in the s[] char array?
Lines 60-61: What happens if the user presses 'Y' instead of 'y'?
Lines 67-71: Why not just have char pointers instead of physically swapping the two strings?
Let me recommend using the modulus operator to get rid of the complicated looping logic.
vhar.myopenid.com
August 12, 2009, August 12, 2009 06:25, permalink
hey buddy thanks for finding errors:)
i wrote that code long back and uploaded it on to my blog i just copied it here and due some html stuff it is changed a little bit
"you are free to change it the way u like"
I don't have compiler readily available so writing them as
MY THOUGHTS:
Line 8,12,14:I thought any human cant have a name more than 20 chars:)
u can use pointers to extend it :)
Line 10,60:It gives you another chance!!!!
this is a fun game i will change my name surely if "flames" between me and
my girl gives the relation "sister;)"
eg:-my name is "jhon adams"(not really) and my girls is "emma watson".
i can use jhon & emma or adams & emma till it says you are lovers!!!
Line 19-23:It has a bug use "if(!strcmp(name1,name2))"
Line 19-23:see line 63 i swapped the names.
Line 42 :this is assumed that names will be <20 chars
Line 60-61:Use if(change_fate=='y'||change_fate=='Y')
Line 67-71:i was weak in pointers at that time so......
"I NEVER THOUGHT THIS SITE IS SO ACTIVE"
Ants
August 12, 2009, August 12, 2009 09:38, permalink
Here's three different refactorings depending on which approach you want to take:
I changed the algorithm in ComputeCommonNumber() to only count alpha's. Works great for "Jack" and "Diane" but has interesting implications for "Phillip" and "Anna": "Jack" and "Diane" lose their A's and count as 7, but "Phillip" and "Anna" will be counted as 11 -- should they be counted as 6 or 1? (Since I never played this game as a kid, and the rules I've found for the game are inconsistent on the net: some say discard all duplicate letters while others only say discard duplicate letters between the names, yet others say only count unique letters. Please change the algorithm to whatever your desired behavior is.)
The final check before return in ComputeCommonNumber() is to ensure that "dean" and "edna" won't return a zero.
I changed the sscanf() calls to fgets() because entering "Jhon Adams" at the first prompt would result in "Jhon" being taken as name1 and "Adams" as name2. Also changed the getchar() to _getch() so that on the next loop, the first name will be read.
#include <stdio.h>
#include <tchar.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define NAME_LEN_MAX 1024
#define SIZEOF_ARRAY(_arr) (sizeof(_arr) / sizeof(_arr[0]))
char * fates[] = {
"FRIEND! not bad can try later;",
"LOVER!!! u r the luckiest being on earth",
"AFFECTION! end up u r life making difference b/w love and affection",
"MARRIAGE!!! a famous saying \"wife is a knife that cuts u r life\"",
"ENEMIES lets wage a war!!!!!!!!!",
"SISTER!!!! i pity you ;)",
};
char * CopyAlphaOnly(char * dst, const char * src)
{
while (*src)
{
if (isalpha(*src))
*dst++ = toupper(*src);
++src;
}
*dst = 0;
return dst;
}
void RemoveDuplicateChars(char * dst, const char * src)
{
while (*src)
{
char ch = toupper(*src);
if (isalpha(ch))
{
char * found = strchr(dst, ch);
if (found)
{
while (found)
{
*found = ' ';
found = strchr(&found[1], ch);
}
}
}
++src;
}
}
int CountAlphaOnly(const char *src)
{
int count = 0;
while (*src)
{
if (isalpha(*src))
++count;
++src;
}
return count;
}
int ComputeCommonNumber(const char * name1, const char * name2)
{
char temp1[NAME_LEN_MAX];
char temp2[NAME_LEN_MAX];
int count;
CopyAlphaOnly(temp1, name1);
CopyAlphaOnly(temp2, name2);
RemoveDuplicateChars(temp1, name2);
RemoveDuplicateChars(temp2, name1);
count = CountAlphaOnly(temp1) + CountAlphaOnly(temp2);
return count ? count : 1;
}
//
// Recursive
//
char * DiscardFate(int i, int arraySize, char * fates[])
{
char * discarded = fates[i];
memmove(&fates[i], &fates[i + 1], sizeof(char *) * (arraySize - i - 1));
return discarded;
}
void RestoreFate(int i, int arraySize, char * fates[], char * fate)
{
memmove(&fates[i + 1], &fates[i], sizeof(char *) * (arraySize - i - 1));
fates[i] = fate;
}
char * ComputeFate(int common, int start, int arraySize, char * fates[])
{
char * selected = fates[0];
if (arraySize > 1)
{
int discard = (start + common - 1) % arraySize;
char * saved = DiscardFate(discard, arraySize, fates);
selected = ComputeFate(common, discard, arraySize - 1, fates);
RestoreFate(discard, arraySize, fates, saved);
}
return selected;
}
//
// Slightly object oriented
//
typedef struct _DISCARDS
{
int count;
int currentPos;
char discarded[SIZEOF_ARRAY(fates)];
} DISCARDS;
void InitDiscards(DISCARDS * discards)
{
int i;
discards->count = 0;
discards->currentPos = -1;
for(i = 0; i < SIZEOF_ARRAY(discards->discarded); i++)
discards->discarded[i] = 0;
}
int GetDiscardsCount(DISCARDS * discards)
{
return discards->count;
}
int MoveToNextAvailable(DISCARDS * discards)
{
do
{
++discards->currentPos;
discards->currentPos %= SIZEOF_ARRAY(discards->discarded);
} while (discards->discarded[discards->currentPos]);
return discards->currentPos;
}
void DiscardCurrentPos(DISCARDS * discards)
{
discards->discarded[discards->currentPos] = 1;
++discards->count;
}
char * ComputeFate2(int common)
{
DISCARDS discards;
InitDiscards(&discards);
while (GetDiscardsCount(&discards) < SIZEOF_ARRAY(fates) - 1)
{
int count = ((common - 1) % (SIZEOF_ARRAY(fates) - GetDiscardsCount(&discards))) + 1;
while(count-- > 0)
MoveToNextAvailable(&discards);
DiscardCurrentPos(&discards);
}
return fates[MoveToNextAvailable(&discards)];
}
//
// Purely procedural
//
char * ComputeFate3(int common)
{
char discarded[SIZEOF_ARRAY(fates)] = { 0 };
int discards = 0;
int arraySize = SIZEOF_ARRAY(fates);
int i;
i = -1;
while (discards < arraySize - 1)
{
int count = ((common - 1) % (arraySize - discards)) + 1;
while(count > 0)
{
i = (i + 1) % arraySize;
if (!discarded[i])
{
count--;
if (count == 0)
{
discarded[i] = !discarded[i];
--i;
++discards;
}
}
}
}
for (i = 0; i < arraySize; ++i)
if (!discarded[i])
return fates[i];
return fates[0];
}
//
// Main logic loop
//
int main()
{
int common;
char name1[NAME_LEN_MAX];
char name2[NAME_LEN_MAX];
printf("FLAMES\n");
do
{
printf("\nenter a name: ");
fgets(name1, SIZEOF_ARRAY(name1), stdin);
printf("\nenter second name: ");
fgets(name2, SIZEOF_ARRAY(name2), stdin);
common = ComputeCommonNumber(name1, name2);
printf("\n%d\n%s", common, ComputeFate(common, 0, SIZEOF_ARRAY(fates), fates));
printf ("\nWanna change ur love?");
} while(toupper(_getch()) == 'Y');
return 0;
}
vishu
August 14, 2009, August 14, 2009 00:36, permalink
sorry buddy a bit late
the rules for playing game are:
let name1="vishu"
name2="suhus"
step 1:
scan every char in first name and see if it matches with any char of second name if it then strike them .
"s" in (name1) matches with "s"(first "s" in name2) cancel them
similarly "u" and "h" cancel outs.
now count the remaining remaining letters since all common chars are cancelled out.
here it is 4 chars remaining.
now write down "flames"
cancel out 4th letter (in this case) "m" then move again in cyclic manner thus the next 4th char is "l"
cancel them like that till a single letter remains thats your fate!!!
Ants
August 14, 2009, August 14, 2009 19:48, permalink
Oh I see. As I said I ran across many variations on the rules.
Given your rules above, your original commonnum() would return 0 rather than your expected 4.
Anyway, to play by the rules outlined above change RemoveDuplicateChars() to:
void RemoveDuplicateChars(char * dst, const char * src)
{
while (*src)
{
char ch = toupper(*src);
if (isalpha(ch))
{
char * found = strchr(dst, ch);
if (found)
*found = ' ';
}
++src;
}
}
Thomas Salvador
November 15, 2009, November 15, 2009 14:27, permalink
hi.
instead of the upper ComputeCommonNumber() i propose an easier one: EasyCommonNumber().
the idea is, that by rules the characters of the first name cancel out the same characters of the second name. that is the 'shu' of vishu cancels the 'suh' of suhus, but leaves the 'us' intact. with other words, one character of the first name cancels at most one character of the second name.
with this we can just count it out:
1. the routine below adds one to each character in the first name.
2. then, it subtracts one of each character in the second name.
3. finally id adds the absolute values for the character counts.
example:
1. leads to a 1 at 'v', 'i', 's', 'h', 'u' .
2. leads to a 0 for 'h', and to a -1 for 's', 'u', leaving the 1 at 'v' and 'i' unchanged.
3. sums this up to 4 (v=1, i=1, s=-1, u=-1).
the toupper just normalizes the writing. it should only count for alphas.
regards,
thomas.
int EasyCommonNumber(const char * name1, const char * name2) {
// use atoi() if you prefer explicit type change
int counts[255];
int result;
int i;
for (i = 0; i < strlen(name1); i++) {
if (isalpha(name1[i])) {
counts[toupper(name1[i])]++;
}
}
for (i = 0; i < strlen(name1); i++) {
if (isalpha(name1[i])) {
counts[toupper(name1[i])]--;
}
}
for (i=0;i<255;i++) {
result+=abs(counts[i]);
}
return result;
}
Thomas salvador
November 15, 2009, November 15, 2009 14:34, permalink
argh. copy and paste bug. in lines 13-14 it should read name2 instead of name1, of course.
regards, thomas.
...
for (i = 0; i < strlen(name2); i++) {
if (isalpha(name2[i])) {
counts[toupper(name2[i])]--;
}
}
...
a little game which give your relation with a girl ;P