My Solution to 2nd Edition Challenge


#1

I found 293 “words” that are also proper nouns:

#import <Foundation/Foundation.h>

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

    @autoreleasepool {
        
        // load the list of words into a string
        NSString *wordsData = [NSString stringWithContentsOfFile:@"/usr/share/dict/words" encoding:NSUTF8StringEncoding error:NULL];
        
        // Break words into an array of strings
        NSArray *words = [wordsData componentsSeparatedByString:@"\n"];
        
        // load the list of proper names into a string
        NSString *namesData = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL];
        
        // Break names into an array of strings
        NSArray *names = [namesData componentsSeparatedByString:@"\n"];
        
        // Establish indexes and limits for both lists
        NSUInteger nextName = 0, nextWord = 0, numNames = [names count], numWords = [words count];
        
        // Create a place to store comparison results and the total number of matching names
        NSComparisonResult res;
        NSUInteger found = 0;
        
        // While there are still more words and names to check
        // (note that this algorithm depends on both lists being sorted)
        while (nextName < numNames && nextWord < numWords) {
            
            // Compare the next word with the next name
            res = [words[nextWord] localizedCaseInsensitiveCompare:names[nextName]];
            switch(res) {
                case NSOrderedAscending:    // the next word sorts before the next name
                    nextWord++;
                    break;
                case NSOrderedSame:         // match found
                    // Determine if the two words do not have the same capitalization
                    if ([words[nextWord] localizedCompare:names[nextName]] != NSOrderedSame) {
                        NSLog(@"%@[%ld] == %@[%ld]",words[nextWord],nextWord,names[nextName],nextName);
                        found++;
                        nextName++;
                    }
                    nextWord++;
                    break;
                case NSOrderedDescending:   // the next word sorts after the next name
                    nextName++;
                    break;
                default:
                    NSLog(@"NSComparisonResult out of range: %ld",(NSUInteger)res);
            }
        }
        NSLog(@"%ld Proper nouns are also words.",found);
    }
    return 0;

#2

I wasn’t very happy with that version because it included a lot of proper nouns that aren’t in the dictionary so I upgraded it to this version which actually checks the dictionary before considering the proper noun a word:

                case NSOrderedSame:         // match found
                    // Determine if the two words do not have the same capitalization
                    if ([words[nextWord] localizedCompare:names[nextName]] != NSOrderedSame) {
                        NSString *wrd = words[nextWord];
                        
                        // Ensure the word exists in the dictionary before including it
                        CFStringRef def = DCSCopyTextDefinition(NULL, CFBridgingRetain(wrd), CFRangeMake(0, [wrd length]));
                        if (def) {
                            NSLog(@"%@[%ld] == %@[%ld]", words[nextWord], nextWord, names[nextName], nextName);
                            found++;
                        }
                        nextName++;
                    }
                    nextWord++;
                    break;

#3

I came up with a little different solution…

[code]NSError * error;

    NSString * wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words" encoding:NSUTF8StringEncoding error:&error];
    if (error)
    {
        NSLog(@"Error with words");
        return 1;
    }
    
    NSString * nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:&error];
    if (error)
    {
        NSLog(@"Error with names");
        return 1;
    }
    
    NSArray * words = [wordString componentsSeparatedByString:@"\n"];
    NSArray * names = [nameString componentsSeparatedByString:@"\n"];
    NSString * targetWord;
    
    for (NSString * name in names)
    {
        targetWord = [name lowercaseString];
        if ([words containsObject:targetWord] && [targetWord length] != 0)
        {
            NSLog(@"The name %@ matches the word %@.", name, targetWord);
        }
    }

[/code]

It just searches the word array for an uncapitalized name.
I check length as the NSArray has an empty name… without the check , it reports at the end that “The name matches the word .” LOL.