ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# KiligWY's solution

## to Meetup in the Objective-C Track

Published at Jul 13 2018 · 0 comments
Instructions
Test suite
Solution

Calculate the date of meetups.

Typically meetups happen on the same day of the week. In this exercise, you will take a description of a meetup date, and return the actual meetup date.

Examples of general descriptions are:

• The first Monday of January 2017
• The third Tuesday of January 2017
• The wednesteenth of January 2017
• The last Thursday of January 2017

The descriptors you are expected to parse are: first, second, third, fourth, fifth, last, monteenth, tuesteenth, wednesteenth, thursteenth, friteenth, saturteenth, sunteenth

Note that "monteenth", "tuesteenth", etc are all made up words. There was a meetup whose members realized that there are exactly 7 numbered days in a month that end in '-teenth'. Therefore, one is guaranteed that each day of the week (Monday, Tuesday, ...) will have exactly one date that is named with '-teenth' in every month.

Given examples of a meetup dates, each containing a month, day, year, and descriptor calculate the date of the actual meetup. For example, if given "The first Monday of January 2017", the correct meetup date is 2017/1/2.

## Setup

There are two different methods of getting set up to run the tests with Objective-C:

• Create an Xcode project with a test target which will run the tests.
• Use the ruby gem `objc` as a test runner utility.

Both are described in more detail here: http://exercism.io/languages/objective-c

### Submitting Exercises

When submitting an exercise, make sure your solution file is in the same directory as the test code.

The submit command will look something like:

``````exercism submit <path-to-exercism-workspace>/objective-c/meetup/Meetup.m
``````

You can find the Exercism workspace by running `exercism debug` and looking for the line beginning with Workspace.

## Source

Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month https://twitter.com/copiousfreetime

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### MeetupTest.m

``````#import <XCTest/XCTest.h>

#if __has_include("MeetupExample.h")
# import "MeetupExample.h"
# else
# import "Meetup.h"
#endif

@interface MeetupTest : XCTestCase

@end

@implementation MeetupTest

- (void)testMonteenthOfMay2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:5]
dayForDayOfWeek:MeetupDayOfWeekMonday andOptions:MeetupOptionsTeenth];
XCTAssertEqualObjects(date, [self dateForMonth:5 day:13 year:2013]);
}

- (void)testSaturteenthOfFebruary2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:2]
dayForDayOfWeek:MeetupDayOfWeekSaturday andOptions:MeetupOptionsTeenth];
XCTAssertEqualObjects(date, [self dateForMonth:2 day:16 year:2013]);
}

- (void)testFirstTuesdayOfMay2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:5]
dayForDayOfWeek:MeetupDayOfWeekTuesday andOptions:MeetupOptionsFirst];
XCTAssertEqualObjects(date, [self dateForMonth:5 day:7 year:2013]);
}

- (void)testSecondMondayOfApril2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:4]
dayForDayOfWeek:MeetupDayOfWeekMonday andOptions:MeetupOptionsSecond];
XCTAssertEqualObjects(date, [self dateForMonth:4 day:8 year:2013]);
}

- (void)testThirdThursdayOfSeptember2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:9]
dayForDayOfWeek:MeetupDayOfWeekThursday andOptions:MeetupOptionsThird];
XCTAssertEqualObjects(date, [self dateForMonth:9 day:19 year:2013]);
}

- (void)testFourthSundayOfMarch2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:3]
dayForDayOfWeek:MeetupDayOfWeekSunday andOptions:MeetupOptionsFourth];
XCTAssertEqualObjects(date, [self dateForMonth:3 day:24 year:2013]);
}

- (void)testLastThursdayOfOctober2013 {
NSDate *date = [[[Meetup alloc] initWithYear:2013 andMonth:10]
dayForDayOfWeek:MeetupDayOfWeekThursday andOptions:MeetupOptionsLast];
XCTAssertEqualObjects(date, [self dateForMonth:10 day:31 year:2013]);
}

- (void)testLastWednesdayOfFebruary2012 {
NSDate *date = [[[Meetup alloc] initWithYear:2012 andMonth:2]
dayForDayOfWeek:MeetupDayOfWeekWednesday andOptions:MeetupOptionsLast];
XCTAssertEqualObjects(date, [self dateForMonth:2 day:29 year:2012]);
}

- (void)testFirstFridayOfDecember2012 {
NSDate *date = [[[Meetup alloc] initWithYear:2012 andMonth:12]
dayForDayOfWeek:MeetupDayOfWeekFriday andOptions:MeetupOptionsFirst];
XCTAssertEqualObjects(date, [self dateForMonth:12 day:7 year:2012]);
}

#pragma mark - Helper method

- (NSDate *)dateForMonth:(int)month day:(int)day year:(int)year {
NSDateComponents *components = [[NSDateComponents alloc] init];
components.month = month;
components.day = day;
components.year = year;

return [[NSCalendar currentCalendar] dateFromComponents:components];
}

@end``````

### Meetup.h

``````#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``````

### Meetup.m

``````#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;
// first dayOfWeek
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; // days in month
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``````