Challenge 2 Solution


#1

I decided to register and submit this as I loved this question and am fairly new to Objective C and I loved trying to find a way to optimise this, my thoughts on this were:

  • Names are all capitalised case
  • What we need to match are lower case and not capitalised case

Because of this I intended to set the names to lowercase and then match it that way and present it as capitalised case:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *nameString = [[NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                         encoding:NSUTF8StringEncoding
                                                         error:NULL] lowercaseString];
        NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                    encoding:NSUTF8StringEncoding
                                                       error:NULL];
        
        // Break it into an array of strings
        // Use NSMutableArray, could be faster if I remove them maybe...
        //NSArray *names = [nameString componentsSeparatedByString:@"\n"];
        //NSArray *words = [wordString componentsSeparatedByString:@"\n"];
        NSMutableArray *names = [NSMutableArray arrayWithArray:[nameString componentsSeparatedByString:@"\n"]];
        NSMutableArray *words = [NSMutableArray arrayWithArray:[wordString componentsSeparatedByString:@"\n"]];
        

        // Go through the array one name at a time
        
        for (NSString *word in words)
        {
            for (NSString *name in names)
            {
                if ([name isEqualToString:word])
                {
                    NSLog(@"%@", [name capitalizedString]);
                    [names removeObject:name];
                    break;
                }
            }
        }
    }
    return 0;
}

It was not faster though, I thought about reducing the names array as I went up but it was not faster - I intend revisiting this once I know a bit more about the language with some optimisations!


#2

Hi Craig,

I see a problem with your code. The book is asking for only the lowercase matches, meaning only the propernames that show up as lowercase in the common words file. The way your code is setup,

if ([name isEqualToString:word])

you will only match the propernames in the common words file, since that is a case sensitive match. Remember that the common words file contains all of the propernames that is in the propername file as well as common names. Your results will include every single word in the Proper name list which is not what you want!