Thread: Target Solver

  1. #1
    HelpingYouHelpUsHelpUsAll
    Join Date
    Dec 2007
    Location
    In your nightmares
    Posts
    223

    Target Solver

    I have been working on creating a target solver for the SMH (see http://www.smh.com.au/entertainment/puzzles/target.html).

    The program is working well except for the part about:
    In making a word, each letter must be used once only.
    The function target receives the nine letters in the form 'tetremoei' where the first letter ('t') is the centre letter. The problem I beleive is the if where I call CountCharsStr not the function itself.
    I have commented out the irrelevant functions that should not have any effect on fixing the problem.

    Code:
    int CountCharsStr(char* pstrBuf, char chAscii){
    	int iCount = 0,iLength = strlen(pstrBuf),iCounter = 0;
    	for (iCounter=0; iCounter<iLength; iCounter++)
    	{
    		if (pstrBuf[iCounter]==chAscii) iCount++;
    	}
    	return iCount;
    }
    
    int target(char *letterBuf)
    {
    	int printwrd, i, outputwrdcnt = 0;
    	FILE *text;
    	char *szLine;
    
    	szLine = (char*) malloc(MAX_PATH);
    	if(szLine==NULL) {
    	    MessageBox(NULL, "Memory couldn't be allocated.", "Target Solver",
    		MB_ICONEXCLAMATION | MB_OK);
    		return 1;
    	}
    	fflush(stdin);
    	text = fopen("words.txt","r");
    	if (!text)    {
    		MessageBox(NULL, "Could not find dictionary.", "Target Solver",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    	while(fgets(szLine,MAX_PATH,text) != NULL)    {
    		if (((strlen(szLine) <= 10) && (strlen(szLine) > 4)) && (strchr(szLine,letterBuf[0]))) printwrd = 1;
    		else continue;
    
    		// Filter out Capitals
    
    		//Filter out '-', ' ' and ','
    
    		for (i=0; i <= strlen(szLine)-2; i++) {
    			if (!strchr(letterBuf,szLine[i]) || CountCharsStr(szLine,letterBuf[i]) > CountCharsStr(letterBuf,letterBuf[i]))				{
    				printwrd = 0;
    				break;
    			}
    		}
    		if (printwrd) {
                            //output szLine
    			outputwrdcnt++;
    		}
    	}
            //Output outputwrdcnt
    	fclose(text);
    	free(szLine);
    	return 0;
    }
    long time no C; //seige
    You miss 100% of the people you don't C;
    Code:
    if (language != LANG_C && language != LANG_CPP)
        drown(language);

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't think you can do both of those checks at the same time (assuming we're looking at the line that starts if !strchr). For instance, suppose your dictionary had the word "mmmm", and m is in your target string, but not til position 7. The variable i will only go to 3, so it will never check whether you have too many m's.

    I see two possibilities: (1) break it up into two loops: one for the is-each-letter-in-the-target and one for the do-I-have-too-many checks; (2) ditch the first check, and make sure that your < condition is satisfied, and that you get > 0 back as well.

  3. #3
    HelpingYouHelpUsHelpUsAll
    Join Date
    Dec 2007
    Location
    In your nightmares
    Posts
    223
    Thanks for the quick reply. I have split it into two loops as I didn't want to ditch the if (!strchr(... as this checks if all the letters in szLine are contained (in or out of order) in letterBuf. This works the same as I started with, as I am not sure exactly how I should break it up. The first for is fine (works perfectly) the second isn't. I am quite sure my logic is correct but it is hard to tell as I can't debug very well. The CountCharsStr line filters out the words that meet the condition, not the other way round. Also as I haven't been able to debug it I am not sure why changing: for (i=0; i <= strlen(szLine)-2; i++) to for (i=0; i <= strlen(szLine)-1; i++) returns 0 words. Also note that I'm reading in words form a text file in the following format, so szLine contains the word followed by '\n':
    aback
    abaft
    abandon
    abandoned
    Code:
    		for (i=0; i <= strlen(szLine)-2; i++) {
    			if (!strchr(letterBuf,szLine[i])) {
    				printwrd = 0;
    				break;
    			}
    		}
    
    		for (i=0; i <= strlen(szLine)-2; i++) {
    			if (CountCharsStr(szLine,letterBuf[i]) > CountCharsStr(letterBuf,letterBuf[i]))	{
    				printwrd = 0;
    				break;
    			}
    		}
    long time no C; //seige
    You miss 100% of the people you don't C;
    Code:
    if (language != LANG_C && language != LANG_CPP)
        drown(language);

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The point of the two for-loops is that they have different boundaries! The first for-loop needs to check every letter in the dictionary word; that's fine. The second for-loop needs to check every letter in the target string; that is, it must go from 0 to 8 every time without fail.
    Last edited by tabstop; 01-14-2008 at 09:00 AM. Reason: fixed boldness

  5. #5
    HelpingYouHelpUsHelpUsAll
    Join Date
    Dec 2007
    Location
    In your nightmares
    Posts
    223
    Thanks, tabstop, I am suprised I didn't try that. It works 100&#37; now.
    long time no C; //seige
    You miss 100% of the people you don't C;
    Code:
    if (language != LANG_C && language != LANG_CPP)
        drown(language);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Makefile Problem: None rule to make target
    By chris24300 in forum Linux Programming
    Replies: 25
    Last Post: 06-17-2009, 09:45 AM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. Tweakable Radar...
    By DoraTehExploda in forum Game Programming
    Replies: 8
    Last Post: 06-07-2005, 10:49 AM
  4. compiler build error
    By KristTlove in forum C++ Programming
    Replies: 2
    Last Post: 11-30-2003, 10:16 AM