Challenge 2 Solution, I avoided lowercasing Proper Names

Saw a lot of solutions that just lowercase the proper names and then just compare that with the words list. Decided to take the longer route to get some extra practice.


#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 *properNameString =
                    [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                              encoding:NSUTF8StringEncoding
                                                 error:NULL];
        NSString *wordString =
                    [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                              encoding:NSUTF8StringEncoding
                                                 error:NULL];
        
        // Break it into an array of strings
        NSArray *properNameArray = [properNameString componentsSeparatedByString:@"\n"];
        NSArray *wordStringArray = [wordString componentsSeparatedByString:@"\n"];
        
        // Put matches into this array
        NSMutableArray *match = [NSMutableArray array];
        
        
        // Go through the array one string at a time
        for (NSString *properName in properNameArray)
        
        {
            for (NSString *word in wordStringArray)
            {
                
                // If the length of properName and word do not match
                // move on to the next word
                if (properName.length != word.length) {
                    continue;
                }
                
                // If the length are the same but the characters are not the same
                // move on to the next word
                else if ([properName compare:word options:NSCaseInsensitiveSearch] != NSOrderedSame)
                {
                    continue;
                }

                // If the two are equal, for example, if both are names with an uppercased character
                // in the beginning, move on to the next word
                
                else if ([properName isEqualToString:word] == YES)
                {
                    continue;
                }
                
                // The match is found here, put a break here to test
                else if ([properName compare:word options:NSCaseInsensitiveSearch] == NSOrderedSame)
                {
                
                   NSLog(@"Found One! Word: %@ ProperName: %@", word, properName);
                   [match addObject:word];
                }
                
                else if ([properName isEqualToString:@""] || [word isEqualToString:@""])
                {
                    continue;
                }
             
             }
          }
        
            NSLog(@"Total Count: %lu", [match count]);
    }
    return 0;
}

Before testing the lengths, you could also check to see if the first characters of the words are different, if so you would continue with the next iteration.

Good suggestion

A better version. First, removes the whitespace and newline character at beginning and end of the two strings. Second, copies the first character from proper name string and the word string and compares the two. If the first character from the word’s list is uppercase, then it will be skipped.


#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 *properNameString =
                    [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                              encoding:NSUTF8StringEncoding
                                                 error:NULL];
        NSString *wordString =
                    [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                              encoding:NSUTF8StringEncoding
                                              error:NULL];
        
        // Trim the whitespace and newline character at beginning and end of string
        NSString *properNameTrimmed = [properNameString stringByTrimmingCharactersInSet:
                                       [NSCharacterSet whitespaceAndNewlineCharacterSet]];
        
        // Trim the whitespace and newline character at beginning and end of string
        NSString *wordStringTrimmed = [wordString stringByTrimmingCharactersInSet:
                                       [NSCharacterSet whitespaceAndNewlineCharacterSet]];
        
        
        // Break it into an array of strings
        NSArray *properNameArray = [properNameTrimmed componentsSeparatedByString:@"\n"];
        NSArray *wordStringArray = [wordStringTrimmed componentsSeparatedByString:@"\n"];
        
        
        // Put matches into this array
        NSMutableArray *match = [NSMutableArray array];
        
        // Declare two unichar variables to hold a single character
        unichar properNameChar;
        unichar wordChar;
        
        
        // Go through the array one string/ProperName at a time
        for (NSString *properName in properNameArray)
        
        {
            
            // Get the first character in properName
            properNameChar = [properName characterAtIndex:0];
            
                
            for (NSString *word in wordStringArray)
            {
              
                wordChar = [word characterAtIndex:0];
                
                    // If wordChar is less than 97, then this is an uppercase character
                    if (wordChar < 97)
                    {
                        continue;
                    }
                
                
                    // If the length of properName and word do not match, move on to the next word
                    else if (properName.length != word.length)
                    {
                    continue;
                    }
                
                
                   // The match is found here, put a break here to test
                    else if ([properName compare:word options:NSCaseInsensitiveSearch] == NSOrderedSame)
                    {
                
                        NSLog(@"Found One! Word: %@ ProperName: %@", word, properName);
                        [match addObject:word];
                    }
                
                
             }
          }
        
            NSLog(@"Total Count: %lu", [match count]);
    }
    return 0;
}

I thought it would be easier to just make the propernames list lowercase, thus here is my code, i got 294 matches:

#import <Foundation/Foundation.h>

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

    //Integer to record the number of matches when comparing the two text
    //files later on.
    NSInteger numOfMatches = 0;
    
    // Read in a file as a huge string (ignoring the possibility of an error)
    //reading the propernames file to an NSString Object
    NSString *nameStringProperNames =
    [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                              encoding:NSUTF8StringEncoding
                                 error:NULL];
    
    //reading the words file to an NSString object
    NSString *nameStringCommonWords =
    [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                              encoding:NSUTF8StringEncoding
                                 error:NULL];
    
    
    
    // Break them both into an array of strings
    
    //ProperNames NSString broken down into an array of sub strings, using the new line character as a delimeter
    NSArray *properNames = [nameStringProperNames componentsSeparatedByString:@"\n"];
    
    //Common words NSString broken down into array of sub strings, using the new line character as a delimeter
    NSArray *commonNames = [nameStringCommonWords componentsSeparatedByString:@"\n"];
    
    // Iterate/Go through the proper names array one index at a time and compare it to the common names
    //one index at a time to see if you find a lower case match
    
    //assign each string in the properNames array to the pn variable
    for (NSString *pn in properNames) {
        
        //make it lowercase
        NSString *lowerpn = [pn lowercaseString];
        
        //Assign each string in the commonNames array to the cn variable
        for (NSString *cn in commonNames){
            
            //check to see if the lower case propername is equal to the current common name string
            if ([cn isEqualTo:lowerpn]){
                //if so, print the current common name
                NSLog(@"%@", cn);
                //increment the numOfMatches variable to record the total number of matches
                numOfMatches +=1;
                
            }

        }
        
    }
    //Print the total number of matches
    NSLog(@"The total number of matches is %lu.", numOfMatches);
    
    }
    

return 0;

}