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

# EggmanQi's solution

## to Meetup in the Objective-C Track

Published at Jan 02 2019 · 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.m
//  exercismOC
//
//  Created by eggman qi on 2019/1/2.
//

#import "Meetup.h"

@interface Meetup ()
@property (nonatomic, strong)NSCalendar *calendar;
@property (nonatomic, assign)NSInteger myYear;
@property (nonatomic, assign)NSInteger myMonth;
@property (nonatomic, assign)NSInteger count;

@end

@implementation Meetup

- (Meetup *)initWithYear:(NSInteger)year andMonth:(NSInteger)month
{
_calendar = [NSCalendar currentCalendar];
_count = 1;
_myYear = year;
_myMonth = month;
return self;
}

- (NSDate *)dayForDayOfWeek:(MeetupWeekDay)weekDay andOptions:(MeetupOptions)options
{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.month = _myMonth;
dateComponents.year = _myYear;

NSDate *oringalDate = [_calendar dateFromComponents:dateComponents];

NSInteger day = [self getNumberOfDaysInMonth:oringalDate];
for (NSInteger i=1; i<=day; i++) {
dateComponents.day = i;
if ([self isDateComponents:dateComponents
matchDayOfWeek:weekDay
andOptions:options]) {
NSDate *date = [_calendar dateFromComponents:dateComponents];
return date;
}
}

return nil;
}

- (NSInteger)getNumberOfDaysInMonth:(NSDate *)targetDate {
NSCalendar *calendar  = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitMonth
forDate:targetDate];
return range.length;
}

- (BOOL)isDateComponents:(NSDateComponents *)targetDataComponents
matchDayOfWeek:(MeetupWeekDay)weekDay
andOptions:(MeetupOptions)options
{
NSDate *date = [_calendar dateFromComponents:targetDataComponents];
targetDataComponents = [_calendar components:NSCalendarUnitMonth|NSCalendarUnitWeekday|NSCalendarUnitWeekOfMonth|NSCalendarUnitDay|NSCalendarUnitYear
fromDate:date];
NSInteger numOfWeekDay = [targetDataComponents weekday];

if (numOfWeekDay != weekDay) {
return NO;
}

if (options == MeetupOptionsLast) {
NSRange weekRange = [_calendar rangeOfUnit:NSCalendarUnitWeekOfMonth
inUnit:NSCalendarUnitMonth
forDate:date];
NSInteger weeksCount=weekRange.length;
NSInteger week = [targetDataComponents weekOfMonth];
if (weeksCount == week) {
return YES;
}
}else if (options == MeetupOptionsTeenth) {
NSInteger day = [targetDataComponents day];
if (day>=13 && day<=19) {
return YES;
}
}else {
if (_count == options) {
return YES;
}
}

_count = _count + 1;

return NO;
}

@end``````