Objective-C 练习题,题目来源 exercism.io ,一共 50 题,见 GitHub 。
第四篇共 10 题。
(一)
(二)
(三)
(五)
# Allergies
题目和测试用例见链接,下同。Allergies
Given a person’s allergy score, determine whether or not they’re allergic to a given item, and their full list of allergies.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #import <Foundation/Foundation.h> typedef NS_ENUM (NSUInteger , Allergy) { AllergenEggs = 1 , AllergenPeanuts = 2 , AllergenShellfish = 4 , AllergenStrawberries = 8 , AllergenTomatoes = 16 , AllergenChocolate = 32 , AllergenPollen = 64 , AllergenCats = 128 , }; @interface Allergies : NSObject - (instancetype )initWithScore:(NSInteger )score; - (BOOL )hasAllergy:(Allergy)allergy; @end #import "Allergies.h" @implementation Allergies { NSInteger _kScore; } - (instancetype )initWithScore:(NSInteger )score { if (self = [super init]) { _kScore = score; } return self ; } - (BOOL )hasAllergy:(Allergy)allergy { return (_kScore & allergy); } @end
# Meetup
Meetup
Calculate the date of meetups.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 #import <Foundation/Foundation.h> typedef NS_ENUM (NSUInteger , MeetupDay) { MeetupDayOfWeekSunday = 1 , MeetupDayOfWeekMonday, MeetupDayOfWeekTuesday, MeetupDayOfWeekWednesday, MeetupDayOfWeekThursday, MeetupDayOfWeekFriday, MeetupDayOfWeekSaturday, }; typedef NS_ENUM (NSUInteger , MeetupOption) { MeetupOptionsFirst = 0 , MeetupOptionsSecond = 7 , MeetupOptionsThird = 14 , MeetupOptionsFourth = 21 , MeetupOptionsLast, MeetupOptionsTeenth, }; @interface Meetup : NSObject - (instancetype )initWithYear:(NSInteger )year andMonth:(NSInteger )month; - (NSDate *)dayForDayOfWeek:(MeetupDay)dayOfWeek andOptions:(MeetupOption)option; @end #import "Meetup.h" @interface Meetup ()@property (nonatomic , assign ) NSInteger year;@property (nonatomic , assign ) NSInteger month;@property (nonatomic , assign ) NSInteger day;@end @implementation Meetup - (instancetype )initWithYear:(NSInteger )year andMonth:(NSInteger )month { if (self = [super init]) { self .year = year; self .month = month; } return self ; } - (NSDate *)dayForDayOfWeek:(MeetupDay)dayOfWeek andOptions:(MeetupOption)option { NSDateComponents *components = [[NSDateComponents alloc] init]; components.year = self .year; components.month = self .month; components.day = 1 ; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *dateComponents = [calendar components:NSCalendarUnitWeekday fromDate:[calendar dateFromComponents:components]]; NSInteger day = 1 ; if (dayOfWeek >= dateComponents.weekday) { day += (dayOfWeek - dateComponents.weekday); } else { day += (dayOfWeek + 7 - dateComponents.weekday); } if (option == MeetupOptionsLast) { NSInteger days = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[calendar dateFromComponents:components]].length; if (day + 28 > days) { day += 21 ; } else { day += 28 ; } } else if (option == MeetupOptionsTeenth) { if (dayOfWeek >= dateComponents.weekday && dateComponents.weekday != 1 ) { day += 14 ; } else { day += 7 ; } } else { day += option; } components.day = day; return [calendar dateFromComponents:components]; } @end
# Anagram
Anagram
Given a word and a list of possible anagrams, select the correct sublist.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #import <Foundation/Foundation.h> @interface Anagram : NSObject - (instancetype )initWithString:(NSString *)string; - (NSArray *)match:(NSArray *)lists; @end #import "Anagram.h" @interface Anagram ()@property (nonatomic , copy ) NSString *string;@end @implementation Anagram - (instancetype )initWithString:(NSString *)string { if (self = [super init]) { self .string = string; } return self ; } - (NSArray *)match:(NSArray *)lists { NSMutableArray *result = [NSMutableArray array]; [lists enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) { NSString *string1 = [obj lowercaseString]; NSString *string2 = [self .string lowercaseString]; if (string1.length == string2.length && ![string1 isEqualToString:string2]) { NSMutableArray *array = [NSMutableArray array]; NSMutableArray *array2 = [NSMutableArray array]; for (NSInteger i = 0 ; i < obj.length; ++i) { [array addObject:[string1 substringWithRange:NSMakeRange (i, 1 )]]; [array2 addObject:[string2 substringWithRange:NSMakeRange (i, 1 )]]; } [array sortUsingComparator:^NSComparisonResult (NSString *obj1, NSString *obj2) { return [obj1 compare:obj2]; }]; [array2 sortUsingComparator:^NSComparisonResult (NSString *obj1, NSString *obj2) { return [obj1 compare:obj2]; }]; if ([array isEqualToArray:array2]) { [result addObject:obj]; } } }]; return result; } @end
# Acronym
Acronym
Convert a long phrase to its acronym
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #import <Foundation/Foundation.h> @interface Acronym : NSObject + (NSString *)abbreviate:(NSString *)input; @end #import "Acronym.h" @implementation Acronym + (NSString *)abbreviate:(NSString *)input { input = [input stringByReplacingOccurrencesOfString:@"[^a-zA-Z ]" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange (0 , input.length)]; __block NSString *result = @"" ; [input enumerateSubstringsInRange:NSMakeRange (0 , input.length) options:NSStringEnumerationByWords usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) { result = [result stringByAppendingString:[[substring substringToIndex:1 ] uppercaseString]]; for (NSInteger i = 1 ; i < substring.length; ++i) { NSString *subStr = [substring substringWithRange:NSMakeRange (i, 1 )]; NSString *subStr2 = [substring substringWithRange:NSMakeRange (i - 1 , 1 )]; if ([subStr isEqualToString:[subStr uppercaseString]] && [subStr2 isEqualToString:[subStr2 lowercaseString]]) { result = [result stringByAppendingString:subStr]; } } }]; return result; } @end
# All Your Base
All Your Base
Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #import <Foundation/Foundation.h> @interface AllYourBase : NSObject + (NSArray *)outputDigitsForInputBase:(NSInteger )inputBase inputDigits:(NSArray *)inputDigits outputBase:(NSInteger )outputBase; @end #import "AllYourBase.h" @implementation AllYourBase + (NSArray *)outputDigitsForInputBase:(NSInteger )inputBase inputDigits:(NSArray *)inputDigits outputBase:(NSInteger )outputBase { NSAssert (inputBase > 1 , @"inputBase > 1" ); NSAssert (outputBase > 1 , @"outputBase > 1" ); NSInteger decimalNumber = 0 ; for (NSInteger i = 0 ; i < inputDigits.count; ++i) { NSInteger inputDigit = [inputDigits[i] integerValue]; NSAssert (inputDigit < inputBase && inputDigit >= 0 , @"inputDigit > 0 && inputDigit < inputBase" ); decimalNumber += (inputDigit * pow(inputBase, inputDigits.count - i - 1 )); } NSInteger index = 0 ; for (; ; ++index) { if (pow(outputBase, index) > decimalNumber) { index--; break ; } } NSMutableArray *result = [NSMutableArray array]; while (index >= 0 ) { NSInteger value = pow(outputBase, index); NSInteger digit = 0 ; if (value > decimalNumber) { value = 0 ; } else { digit = decimalNumber / value; } [result addObject:@(digit)]; decimalNumber -= (value * digit); index--; } return result; } @end
# Largest Series Product
Largest Series Product
Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #import <Foundation/Foundation.h> @interface LargestSeriesProduct : NSObject - (instancetype )initWithNumberString:(NSString *)string; - (long )largestProduct:(NSInteger )product; @end #import "LargestSeriesProduct.h" @interface LargestSeriesProduct ()@property (nonatomic , copy ) NSString *string;@end @implementation LargestSeriesProduct - (instancetype )initWithNumberString:(NSString *)string { if (self = [super init]) { self .string = string; } return self ; } - (long )largestProduct:(NSInteger )length { NSAssert (self .string.length >= length && length >= 0 , @"length <= string.length && length >= 0" ); NSAssert (([[NSPredicate predicateWithFormat:@"SELF MATCHES %@" , @"^[0-9]*$" ] evaluateWithObject:self .string]), @"String contains non-numeric" ); if (length == 0 ) { return 1 ; } long largestProduct = 0 ; for (NSInteger i = 0 ; i <= self .string.length - length; ++i) { NSString *substring = [self .string substringWithRange:NSMakeRange (i, length)]; if ([substring containsString:@"0" ]) { continue ; } __block long product = 1 ; [substring enumerateSubstringsInRange:NSMakeRange (0 , length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) { product *= [substring integerValue]; }]; largestProduct = MAX(largestProduct, product); } return largestProduct; } @end
# Pangram
Pangram
Determine if a sentence is a pangram.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #import <Foundation/Foundation.h> @interface Pangram : NSObject + (BOOL )isPangram:(NSString *)string; @end #import "Pangram.h" @implementation Pangram + (BOOL )isPangram:(NSString *)string { __block NSString *lowercaseString = [string lowercaseString]; NSString *str = @"abcdefghijklmnopqrstuvwxyz" ; __block BOOL isPangram = YES ; [str enumerateSubstringsInRange:NSMakeRange (0 , str.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) { if (![lowercaseString containsString:substring]) { isPangram = NO ; *stop = YES ; } }]; return isPangram; } @end
# Transpose
Transpose
Take input text and output it transposed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #import <Foundation/Foundation.h> @interface Transpose : NSObject + (NSArray *)transpose:(NSArray *)array; @end #import "Transpose.h" @implementation Transpose + (NSArray *)transpose:(NSArray *)array { NSInteger length = 0 ; for (NSString *sunstring in array) { length = MAX(length, sunstring.length); } NSMutableArray *result = [NSMutableArray array]; for (NSInteger i = 0 ; i < length; ++i) { NSString *string = @"" ; for (NSInteger j = 0 ; j < array.count; ++j) { NSString *obj = array[j]; if (obj.length > i) { string = [string stringByAppendingString:[obj substringWithRange:NSMakeRange (i, 1 )]]; } else { string = [string stringByAppendingString:@" " ]; } } while ([string hasSuffix:@" " ]) { string = [string substringToIndex:string.length - 1 ]; } [result addObject:string]; } return result; } @end
# Binary Search
Binary Search
Implement a binary search algorithm.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #import <Foundation/Foundation.h> @interface BinarySearch : NSObject @property (nonatomic , strong ) NSArray *list;@property (nonatomic , assign ) NSInteger middle;- (instancetype )initWithArray:(NSArray *)array; - (NSInteger )searchFor:(NSInteger )number; @end #import "BinarySearch.h" @implementation BinarySearch - (instancetype )initWithArray:(NSArray *)array { NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult (NSNumber *obj1, NSNumber *obj2) { return [obj1 integerValue] > [obj2 integerValue]; }]; if (![array isEqualToArray:sortedArray]) { return nil ; } if (self = [super init]) { self .list = array; self .middle = array.count / 2 ; } return self ; } - (NSInteger )searchFor:(NSInteger )number { NSInteger middle = self .list.count / 2 ; NSInteger middleValue = [self .list[middle] integerValue]; NSArray *subarray = self .list; do { if (number == middleValue) { return [self .list indexOfObject:subarray[middle]]; } if (middle == 0 ) { return NSNotFound ; } if (number > middleValue) { subarray = [subarray subarrayWithRange:NSMakeRange (middle + 1 , subarray.count % 2 == 0 ? middle - 1 : middle)]; } else { subarray = [subarray subarrayWithRange:NSMakeRange (0 , middle)]; } middle = subarray.count / 2 ; middleValue = [subarray[middle] integerValue]; } while (YES ); return NSNotFound ; } @end
# Crypto Square
Crypto Square
Implement the classic method for composing secret messages called a square code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #import <Foundation/Foundation.h> @interface CryptoSquare : NSObject @property (nonatomic , assign ) NSInteger numberOfColumns;@property (nonatomic , strong ) NSArray *plaintextSegments;@property (nonatomic , copy ) NSString *cipherText;@property (nonatomic , copy ) NSString *normalizedCipherText;@property (nonatomic , copy ) NSString *normalizePlaintext;- (instancetype )initWithText:(NSString *)text; @end #import "CryptoSquare.h" @interface CryptoSquare ()@property (nonatomic , assign ) NSInteger numberOfRows;@end @implementation CryptoSquare - (instancetype )initWithText:(NSString *)text { if (self = [super init]) { self .normalizePlaintext = [[text lowercaseString] stringByReplacingOccurrencesOfString:@"[^a-z0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange (0 , text.length)]; } return self ; } - (NSInteger )numberOfColumns { for (NSInteger c = 1 ; c <= self .normalizePlaintext.length; ++c) { NSInteger r = self .normalizePlaintext.length / c + (self .normalizePlaintext.length % c > 0 ? 1 : 0 ); if (c >= r && c - r <= 1 ) { self .numberOfRows = r; return c; } } return 0 ; } - (NSArray *)plaintextSegments { return [self segments:self .normalizePlaintext]; } - (NSString *)cipherText { NSArray *array = self .plaintextSegments; NSMutableString *result = [NSMutableString string]; for (NSInteger i = 0 ; i < self .numberOfColumns; ++i) { for (NSInteger j = 0 ; j < array.count; ++j) { if ([array[j] length] > i) { [result appendString:[array[j] substringWithRange:NSMakeRange (i, 1 )]]; } } } return result; } - (NSString *)normalizedCipherText { return [[self segments:self .cipherText] componentsJoinedByString:@" " ]; } - (NSArray *)segments:(NSString *)text { NSInteger c, r; if ([text isEqualToString:self .normalizePlaintext]) { c = self .numberOfColumns; r = self .numberOfRows; } else { c = self .numberOfRows; r = self .numberOfColumns; } NSMutableArray *array = [NSMutableArray array]; for (NSInteger i = 0 ; i < r; ++i) { if (i < r - 1 ) { [array addObject:[text substringWithRange:NSMakeRange (i * c, c)]]; } else { [array addObject:[text substringFromIndex:i * c]]; } } return array; } @end