Interview puzzles in Objective-C
It seems to be difficult (in Objective-C) to find a coherent post about those tricky puzzles that sometimes crop up so I thought I'd post one 😀.
String Puzzles
Reverse a string
- (NSString *)reverseString:(NSString *)originalString {
int lengthOfString = [originalString length];
NSMutableString *reorderedString = [[[NSMutableString alloc] initWithCapacity:lengthOfString] autorelease];
while (lengthOfString > 0) {
NSString *element = [NSString stringWithFormat:@"%C", [originalString characterAtIndex:--lengthOfString]];
[reorderedString appendString:element];
}
return reorderedString;
}
Reverse a string 2
- (NSString *)reverseString:(NSString *)originalString {
int lengthOfString = [originalString length];
NSMutableString *reorderedString = [[[NSMutableString alloc] initWithCapacity:lengthOfString] autorelease];
for (int x = 0; x < lengthOfString; x++) {
NSString *element = [NSString stringWithFormat:@"%C", [originalString characterAtIndex:x]];
[reorderedString insertString:element atIndex:0];
}
return reorderedString;
}
Reverse a string and keep word ordering
- (NSString *)reverseStringInOrder:(NSString *)originalString {
NSArray *splitOriginalString = [originalString componentsSeparatedByString:@" "];
NSMutableString *reorderedString = [[[NSMutableString alloc] initWithCapacity:[originalString length]] autorelease];
for (int x = 0; x < [splitOriginalString count]; x++) {
NSString *splitString = [splitOriginalString objectAtIndex:x];
NSString *reorderedSplitString = [self reverseString:splitString]; //pick one of the above implementations
if (x != 0) {
[reorderedString appendString:@" "];
}
[reorderedString appendString:reorderedSplitString];
}
return reorderedString;
}
Sort words into alphabetical order
- (NSString *)sortWordsInStringIntoAlphabeticalOrder:(NSString *)originalString {
NSMutableArray *wordArray = [[originalString componentsSeparatedByString:@" "] mutableCopy];
[wordArray sortUsingSelector:@selector(caseInsensitiveCompare:)];
NSMutableString *returnString = [[NSMutableString alloc] init];
for (int x = 0; x < [wordArray count]; x++) {
if (x != 0) {
[returnString appendString:@" "];
}
[returnString appendString:[wordArray objectAtIndex:x]];
}
return returnString;
}
Determine if string can be reassembled to a Palindrome
- (BOOL)isPalindromic:(NSString *)string {
NSString *caseInsensitiveString = [string lowercaseString];
int lengthOfString = [string length];
if (lengthOfString == 0) {
return FALSE;
}
NSMutableDictionary *characterBin = [[[NSMutableDictionary alloc] init] autorelease];
if (lengthOfString > 1) {
//check properties
for (int x = 0; x < lengthOfString; x++) {
char charAtIndex = [caseInsensitiveString characterAtIndex:x];
NSString *key = [NSString stringWithFormat:@"%C", charAtIndex];
if ([characterBin valueForKey:key] != nil) {
int countOfCharacter = [[characterBin objectForKey:key] intValue];
[characterBin setObject:[[NSNumber alloc] initWithInt:++countOfCharacter] forKey:key];
} else {
[characterBin setObject:[[NSNumber alloc] initWithInt:1] forKey:key];
}
}
BOOL foundOddCharacter = FALSE;
for (NSString *key in [characterBin allKeys]) {
if (([[characterBin objectForKey:key] intValue]%2) != 0) {
if (foundOddCharacter) {
return FALSE;
} else {
foundOddCharacter = TRUE;
}
}
}
return TRUE;
} else {
return TRUE;
}
}
Find matching characters in two strings
- (NSString *)determineMatchingCaseInsensitiveCharactersInStringsOne:(NSString *)stringOne two:(NSString *)stringTwo {
NSMutableDictionary *stringOneDict = [NSMutableDictionary dictionaryWithCapacity:[stringOne length]];
for (NSUInteger index = 0; index < [stringOne length]; index++) {
NSString *key = [[NSString stringWithFormat:@"%c", [stringOne characterAtIndex:index]] lowercaseString];
if (![key isEqualToString:@" "]) {
[stringOneDict setObject:[NSNumber numberWithBool:NO] forKey:key];
}
}
NSMutableString *charactersFromBoth = nil;
for (NSUInteger index = 0; index < [stringTwo length]; index++) {
NSString *potentialKey = [[NSString stringWithFormat:@"%c", [stringTwo characterAtIndex:index]] lowercaseString];
if (![potentialKey isEqualToString:@" "]) {
NSNumber *characterExistsInBoth = [stringOneDict objectForKey:potentialKey];
if (characterExistsInBoth) {
if (!charactersFromBoth) {
charactersFromBoth = [NSMutableString string];
}
[charactersFromBoth appendString:potentialKey];
}
}
}
return charactersFromBoth;
}
Number Puzzles
Convert Decimal to Binary
- (NSString *)convertDecimalToBinary:(int)decimalNumber {
if (decimalNumber > 1) {
NSMutableString *binaryRepresentation = [[[NSMutableString alloc] init] autorelease];
while (decimalNumber > 0) {
int mod = decimalNumber % 2;
[binaryRepresentation insertString:[NSString stringWithFormat:@"%d", mod] atIndex:0];
decimalNumber = (decimalNumber/2);
}
return binaryRepresentation;
} else {
return [NSString stringWithFormat:@"%d", decimalNumber];
}
}
Find GCD (Greatest Common Denominator) shared between two numbers
- (int)GCDBetweenLowest:(int)lowest highest:(int)highest {
if (lowest == 0 || highest == 0) {
return 0;
}
if (lowest == highest) {
return lowest;
}
if (highest%lowest == 0) {
return lowest;
}
if (!(lowest%2 == 0 && highest%2 == 0)) {
return 1;
}
int lowestUpperBounds = lowest/2;
//get lowest and highest factors
for (int x = lowestUpperBounds; x >= 2; x--) {
if (lowest%x == 0 && highest%x == 0) {
return x;
}
}
return 1;
}
Determine if a given value is a prime number
- (BOOL)isPrime:(long)possiblePrime {
if (possiblePrime == 1) {
return FALSE;
}
if (possiblePrime == 2) {
return TRUE;
}
if (possiblePrime%2 == 0) {
return FALSE;
}
double doubleSquareRoot = sqrt((double)possiblePrime);
int intSquareRoot = (int)doubleSquareRoot;
double outcomeOfSquareRoots = doubleSquareRoot - intSquareRoot;
if (outcomeOfSquareRoots == 0) {
return FALSE;
}
for (int x = 3; x < doubleSquareRoot; x+=2) {
if (number%x == 0) {
return FALSE;
}
}
return TRUE;
}
Generate list of prime numbers
- (NSArray *)generateAllPrimeNumbersUntil:(long)max {
NSMutableArray *primeArray = [[NSMutableArray alloc] init];
if (max == 2) {
[primeArray addObject:[[NSNumber alloc] initWithInt:2]];
}
for (int x = 3; x < max; x=x+2) {
if ([self isPrime:x]) {
[primeArray addObject:[[NSNumber alloc] initWithInt:x]];
}
return primeArray;
}
}
Determine if number is power of 2
- (BOOL)isNumberPositivePowerOfTwo:(NSUInteger)possiblePower {
if (possiblePower == 0 || possiblePower == 1 || possiblePower == 2) {
return YES;
}
if (possiblePower % 2 != 0) {
return NO;
}
while(possiblePower > 2) {
possiblePower = possiblePower/2;
if (possiblePower == 2) {
return YES;
}
}
return NO;
}
BuzzFizz
This used to be a favourite of Google. The problem is: given an upper boundary, print "Buzz" for every occurrence where the current index is divisible by 3, print "Fizz" for every occurrence where the current index is divisible by 3 and "BuzzFizz" for every occurrence where the current index is divisible by 3 and 5.
- (void)printBuzzFizzForMaximumUpperBoundary:(NSUInteger)upperBoundary {
for (NSUInteger index = 1; index < upperBoundary; index++) {
if (index % 3 == 0 && index % 5 == 0) {
NSLog(@"BuzzFizz for index: %lu", (unsigned long)index);
} else if (index % 3 == 0) {
NSLog(@"Buzz for index: %lu", (unsigned long)index);
} else if (index % 5 == 0) {
NSLog(@"Fizz for index: %lu", (unsigned long)index);
}
}
}