Challenge solution using enumerateObjectsUsingBlock: method


#1

I went through the documentation to figure out how to access the index during fast enumeration. This is my proposed solution.

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

@autoreleasepool {
    

    // Read in a file as a huge string (ignoring the possibility of an error)
    NSString *wordString
                = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                            encoding:NSUTF8StringEncoding
                                               error:NULL];
    
    // Break it into an array of strings
    NSArray *words = [wordString componentsSeparatedByString:@"\n"];
 
    // Keep a record of results where proper names are also regular words
    NSMutableArray *common = [NSMutableArray array];
    
    // Let's try figuring out the double names
    // Use the enumerateObjectsUsingBlock: method to also keep track of index of enumerated item

    [words enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        
        // All words are ordered. We take the first index and compare it to the next.
        // If they are equal - we can conclude both that the proper name is also a regular word
        
        // first object
        NSString *a = obj;
        // second object
        NSString *b;
        
        // We assign b with the object from next index unless we reached the last item of the array
        if (idx < words.count - 1){
        b = words[idx+1];
        } else {
            NSLog(@"Reached the end");
            stop = YES;
        }
        
        // compare a with b
        if ([a caseInsensitiveCompare:b] == NSOrderedSame) {
            NSLog(@"These are the same: %@ and %@", a, b);
            
            // For extra insights we add it to common so we can count the # of results.
            [common addObject:a];
        }
        
        
    }];
    
    NSLog(@"In total there are %ld words found that are the same", (unsigned long)[common count]);
    
}
return 0;

}
[/code]

In total there are 1515 words found that are the same.


#2

My assumption above were wrong. At least the implementation did not take into account that apart from being duplicates, the results might not be actual ‘proper names’. I’ve added a new check to take care of this. Basically I’m checking whether the names array contains the duplicate word object.

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

@autoreleasepool {
    

    // Read the propertNames file as a huge string
    
    NSString *namesString
                = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                            encoding:NSUTF8StringEncoding
                                               error:NULL];
    
    // Read the words file as a huge string (ignoring the possibility of an error)
    NSString *wordString
                = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                            encoding:NSUTF8StringEncoding
                                               error:NULL];
    
    
    
    // Break it into an array of strings
    
    NSArray *names = [namesString componentsSeparatedByString:@"\n"];
    NSArray *words = [wordString componentsSeparatedByString:@"\n"];
 
    // Keep a record of duplicate results from the words array
    NSMutableArray *common = [NSMutableArray array];
    
    // Keep a record of actual matches where the duplicate results are actual proper names
    NSMutableArray *matches = [NSMutableArray array];
    
    // Let's try figuring out the double names
    // Use the enumerateObjectsUsingBlock: method to also keep track of index of enumerated item

    [words enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        
        // All words are ordered. We take the first index and compare it to the next.
        // If they are equal - we add it to the common array
        
        // first object
        NSString *a = obj;
        // second object
        NSString *b;
        
        // We assign b with the object from next index unless we reached the last item of the array
        if (idx < words.count - 1){
        b = words[idx+1];
        } else {
            NSLog(@"Reached the end");
            stop = YES;
        }
        
        // compare a with b
        if ([a caseInsensitiveCompare:b] == NSOrderedSame) {
            NSLog(@"These are the same: %@ and %@", a, b);
            
            // For extra insights we add it to common so we can count the # of results.
            [common addObject:a];
            
            // Let's check whether the common results are actual proper names.
            if ([names containsObject:a]) {
                
                [matches addObject:a];
                NSLog(@"%@ is both a proper name and a common word", a);
            }
            
        }
        
        
    }];
    
    NSLog(@"In total there are %lu words found that are the same", [common count]);
    NSLog(@"In total there are %lu words that are actual propernames", [matches count]);

    
}
return 0;

}
[/code]

result:

In total there are 1515 words found that are the same
In total there are 293 words that are actual propernames