Quickest solution I found for challenge 2


#1

Let me know what you think…

int counter = 0;

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 *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        
        // Break it into an array of strings
        NSArray *names = [nameString componentsSeparatedByString:@"\n"];
        NSArray *words = [wordString componentsSeparatedByString:@"\n"];
    
        
        // Go through the names array one string at a time
        for (NSString *n in names)
        {
            // We know 2 things:
            //      1. The words array contains every string the names array holds
            //      2. The capitalized version of an equal string comes immediately before the lowercase version
            
            // Knowing those 2 things, we can expedite the looping of the "words" array by starting the loop at the index of "n" +1 (within the "words" loop
            
            for (NSUInteger j = ([words indexOfObject:n] + 1); j < [words count]; j++)
                {                    
                    if ([n caseInsensitiveCompare:[words objectAtIndex: j]] == NSOrderedSame)
                    {
                        NSLog(@"%@ and %@ are equal", n, [words objectAtIndex: j]);
                        counter ++;
                    }
                }
    
        }
        
        NSLog(@"%d", counter);
    }
    return 0;
}

#2

By adding a counter to keep track of the inner loops index each time through, I was able to shave an additional 6 seconds off the total loop time :stuck_out_tongue:

// This keeps track of the index of j on completion of the inner loop
        NSUInteger indexCounter = 0;
        
        // Go through the names array one string at a time
        for (NSString *n in names)
        {
            // We know 2 things:
            //      1. The words array contains every string the names array holds
            //      2. The capitalized version of an equal string comes immediately before the lowercase version
            
            // By keeping track of what index "j" represented on the loops last run, we can expedite the looping of the "words" array by starting the loop at the
            // index of "j" +1. The longer the loop runs, the shorter the loop gets.
            
            for (NSUInteger j = indexCounter + 1; j < [words count]; j++)
                {                    
                    if (([n caseInsensitiveCompare:[words objectAtIndex: j]] == NSOrderedSame) && (!([n isEqualToString:[words objectAtIndex: j]])))
                    {
                        NSLog(@"%@ and %@ are equal", n, [words objectAtIndex: j]);
                        indexCounter = j++;
                        matches++;
                    }
                    
                }
    
        }
        
        NSLog(@"%d", matches);
    }
    return 0;
}