My Solution to Challenge 2


#1

My Solution. Literally took forever to make.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        // Read in a file as a huge string (ignoring the possibility of an error)
        NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        NSString *wordsString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                          encoding:NSUTF8StringEncoding
                                                             error:NULL];
        
        // Make all Proper Names Lower Cased
        NSString *lowercaseProperNames = [nameString lowercaseString];
        
        // Break it into an array of strings
        NSArray *properNames = [lowercaseProperNames componentsSeparatedByString:@"\n"];
        NSArray *wordNames = [wordsString componentsSeparatedByString:@"\n"];
        
        // Set BOOL variable for testing
        BOOL isEqualTo;
        int counter = 0;
        
        // Outer for loop.  Loop through array of ProperNames which are all lower case
        for (NSString *names in properNames) {

            // Check to see if a Proper name exists
            if ([names length] == 0)
                // If there is nothing, then move on to the next Proper name in the array
                continue;

                // Inner for loop.  Loop through array of Words
            for (NSString *words in wordNames) {

               // Check if a word even exists
                if ([words length] == 0)
               //If no word exists then move on to the next one.
                    continue;

                // Test if Proper names and words are equal. Since names is all lower case they should match up with the lower cased words
                isEqualTo = [names isEqualToString: words];
                
                // If they match then print out the Proper name and word.  Increment counter
                if (isEqualTo == YES)  {
                  NSLog(@"\nProper Name: %@ and Regular word: %@ match\n", names, words);
                        //Increment counter
                        counter++;
                        
                    
                }
   
                }
            
            }
        // Should come out to be 293
        NSLog(@"Total matches: %d", counter);
   
 
   return 0;
}
}

#2

[quote]... for (NSString *names in properNames) { ... if ([names length] == 0) ... for (NSString *words in wordNames) { ... if ([words length] == 0) ... ... isEqualTo = [names isEqualToString: words]; ... if (isEqualTo == YES) { NSLog (@"\nProper Name: %@ and Regular word: %@ match\n", names, words); ... } ... [/quote]
Using words and names (in plural form) to denote singular things makes the code confusing .


#3

My solution doesn’t seem to work and I can’t figure out why can someone help me out? it checks everything and returns nothing when I run it… I was told to take the names out of the words string because from what I can tell it will remove only the names (because it is case sensitive) within the words string and not the words themselves (because they are lowercase unlike the proper names contained in the words string)

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //Read in a file as a huge string (ignoring the possibility of an error)
        NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        
        //Read in a file as a huge string this time for regular words
        NSString *regularWordsString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                                 encoding:NSUTF8StringEncoding
                                                                    error:NULL];
        //Break the words in to an array of strings
        NSArray *regularWords = [regularWordsString componentsSeparatedByString:@"\n"];
        
        //break it into an array of strings
        NSArray *names = [nameString componentsSeparatedByString:@"\n"];
        
        //Change the words to not include names
        NSMutableArray *regularWords2;
        [regularWords2 addObjectsFromArray:regularWords];
            [regularWords2 removeObjectsInArray:names];
        
        //Count the number of names and the number of words
        NSUInteger nameCount = [names count];
        NSUInteger wordCount = [regularWords2 count];
        
        //Write a for loop that brings one name at a time
        NSString *n;
        NSString *w;
        
        for (int i = 0; i < nameCount; i++){
            
            //make a variable that contains the one name
            n = [names objectAtIndex:i];
                
            //write a loop that brings up every word
            for(int j = 0; j < wordCount; j++){
                    
                    //make a variable containing each word
                w = [regularWords2 objectAtIndex: j];
                    
                // was a match found?
                if ([n caseInsensitiveCompare:w] == NSOrderedSame) {
                    NSLog(@"%@ is a name", n);
                    NSLog(@"%@ is a word", w);
                     }
                
                
            }
        }
            
    }
    
    return 0;
}

#4

[quote] ... //Change the words to not include names NSMutableArray *regularWords2; [regularWords2 addObjectsFromArray:regularWords]; [regularWords2 removeObjectsInArray:names]; ... [/quote]
That is because your regularWords2 variable is not initialised!

You must initialise it by assigning a mutable array to it.


#5

[quote=“OkayGreat”]My Solution. Literally took forever to make.

[code]
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    // Read in a file as a huge string (ignoring the possibility of an error)
    NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                     encoding:NSUTF8StringEncoding
                                                        error:NULL];
    NSString *wordsString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                      encoding:NSUTF8StringEncoding
                                                         error:NULL];
    
    // Make all Proper Names Lower Cased
    NSString *lowercaseProperNames = [nameString lowercaseString];
    
    // Break it into an array of strings
    NSArray *properNames = [lowercaseProperNames componentsSeparatedByString:@"\n"];
    NSArray *wordNames = [wordsString componentsSeparatedByString:@"\n"];
    
    // Set BOOL variable for testing
    BOOL isEqualTo;
    int counter = 0;
    
    // Outer for loop.  Loop through array of ProperNames which are all lower case
    for (NSString *names in properNames) {

        // Check to see if a Proper name exists
        if ([names length] == 0)
            // If there is nothing, then move on to the next Proper name in the array
            continue;

            // Inner for loop.  Loop through array of Words
        for (NSString *words in wordNames) {

           // Check if a word even exists
            if ([words length] == 0)
           //If no word exists then move on to the next one.
                continue;

            // Test if Proper names and words are equal. Since names is all lower case they should match up with the lower cased words
            isEqualTo = [names isEqualToString: words];
            
            // If they match then print out the Proper name and word.  Increment counter
            if (isEqualTo == YES)  {
              NSLog(@"\nProper Name: %@ and Regular word: %@ match\n", names, words);
                    //Increment counter
                    counter++;
                    
                
            }

            }
        
        }
    // Should come out to be 293
    NSLog(@"Total matches: %d", counter);

return 0;
}
}

[/code][/quote]

I went about mine the same way, in that I look for lowercase matches and it works so I’m glad to see that. I did a few things differently, such as changing to lowercase in the for loop on each instance instead of creating the array in lowercase.


#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
          // Read in a file as a huge string (ignoring the possibility of an error)
        NSString *nameString =
        [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                  encoding:NSUTF8StringEncoding
                                     error:NULL];
        
        // Read in the word file the same way
        NSString *wordString =
        [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                  encoding:NSUTF8StringEncoding
                                     error:NULL];
        
        // Break both into an array of strings
        NSArray *names = [nameString componentsSeparatedByString:@"\n"];
         NSArray *words = [wordString componentsSeparatedByString:@"\n"];
        
        // Go through the array one string at a time
        for (NSString *n in names) {
            
            // Go through the list of words one at a time
            
            for (NSString *w in words)
            {
           //  Make names lowercase so we can look for lowercase versions in the word list they are the only matches we need.
                
               NSString *lowerCase = [n lowercaseString];
                
                
                BOOL found = [lowerCase isEqualToString:w];
                           
                           // Was it found?
                           if (found) {
                               NSLog(@"%@", [n lowercaseString]);
                           }
                           
            }
                        
           
        }
        
        
        
    }
    return 0;
}

#6

Also after reading on here I added a break in my loop once it finds a match.

It lowered the number of checks from 308,776,083 to 273,861,512


#7

I did mine in the same way as you you magicmike, only I converted to lower case before entering the loop. So the source file I was working with, was already lowercase.

I work a lot with scripts (a mixture of batch and bash, using Cygwin) at work, so my thought process is get the source file into a format that you can use and (more importantly when scripting) troubleshoot easily, before moving onto the next step.
I like the idea of converting to lowercase within the loop, but I’m wondering. Is it more efficient doing it this way? As the program is having to perform an extra step each time the loop runs, I’m thinking its more efficient to do it in one block at the start, than repeatedly do it for smaller chunks of data?
I’d be interested to find out.

My code for challenge 2 is here: viewtopic.php?f=453&t=9154