#import <Foundation/Foundation.h>
#import <stdarg.h>

/// @interface //////////////////////////////////////////////////
@interface NSArray (List)
-(NSInteger)integerValueAtIndex:(NSUInteger)index;
-(NSInteger)firstInteger;
-(NSInteger)secondInteger;
-(NSInteger)thirdInteger;
-(NSInteger)fourthInteger;
-(NSMutableArray*)sortedArrayWithAscending:(BOOL)ascending; // NSNumber* を要素に持つ配列をソート
-(NSMutableArray*)unique;
@end

@interface NSMutableArray (List)
+(NSMutableArray*)arrayWithNumbers:(NSInteger)count, ...; // 要素数, 数1, 数2, ... から NSMutableArray<NSNumber*> オブジェクトを生成
-(NSMutableArray*)unshift:(id)element;
-(id)shift;
-(NSMutableArray*)push:(id)element;
-(id)pop;
@end

@interface NSString (Split)
-(NSMutableArray*)componentsSeparatedByCharacter:(unichar)separator;
-(NSMutableArray*)numbersSeparatedByString:(NSString*)separator;
-(NSMutableArray*)numbersSeparatedByCharacter:(unichar)separator;
-(NSMutableArray*)splitCharacterEvery:(NSUInteger)number;
-(NSMutableArray*)characters;
-(unichar)firstCharacter;
-(unichar)lastCharacter;
-(NSString*)leadingSubstringWithLength:(NSUInteger)length;
-(NSString*)trailingSubstringWithLength:(NSUInteger)length;
@end

@interface NSMutableString (List)
-(NSMutableString*)unshift:(NSString*)string;
-(NSString*)shiftWithLength:(NSUInteger)length;
-(NSMutableString*)push:(NSString*)string;
-(NSString*)popWithLength:(NSUInteger)length;
@end

@interface StdIO : NSObject
+(NSMutableString*)stringFromStdIn;
+(NSMutableArray*)stringsFromStdInSeparatedByString:(NSString*)separator;
+(NSMutableArray*)stringsFromStdInSeparatedByCharacter:(unichar)separator;
+(NSMutableArray*)numbersFromStdInSeparatedByString:(NSString*)separator;
+(NSMutableArray*)numbersFromStdInSeparatedByCharacter:(unichar)separator;
+(void)put:(char*)format, ...;
+(void)puts:(NSString*)format, ...;
@end


/// @implementation //////////////////////////////////////////////////

@implementation NSArray (List)
-(NSInteger)integerValueAtIndex:(NSUInteger)index
{
	return [[self objectAtIndex:index] integerValue];
}

-(NSInteger)firstInteger
{
	return [self integerValueAtIndex: 0];
}

-(NSInteger)secondInteger
{
	return [self integerValueAtIndex: 1];
}

-(NSInteger)thirdInteger
{
	return [self integerValueAtIndex: 2];
}

-(NSInteger)fourthInteger
{
	return [self integerValueAtIndex: 3];
}

-(NSMutableArray*)sortedArrayWithAscending:(BOOL)ascending
{
	NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey: @"self" ascending: ascending];
	NSArray *descriptors = [NSArray arrayWithObject: descriptor];
	NSArray *sortedArray = [self sortedArrayUsingDescriptors: descriptors];
	return [NSMutableArray arrayWithArray: sortedArray];
}

-(NSMutableArray*)unique
{
	NSMutableArray *result = [NSMutableArray array];
	NSEnumerator *enumerator = [self objectEnumerator];
	id object;
	while ((object = [enumerator nextObject])) {
		if (![result containsObject: object]) {
			[result push: object];
		}
	}
	return result;
}
@end

@implementation NSMutableArray (List)
+(NSMutableArray*)arrayWithNumbers:(NSInteger)count, ...
{
	va_list numbers;
	va_start(numbers, count);
	NSMutableArray *array = [NSMutableArray array];
	
	for (NSInteger i = 0; i < count; i++) {
		[array push: [NSNumber numberWithInt:va_arg(numbers, NSInteger)]];
	}
	
	va_end(numbers);	
	return array;
}

-(NSMutableArray*)unshift:(id)element
{
	[self insertObject: element atIndex: 0];
	return self;
}

-(id)shift
{
	if ([self count] > 0) {
		id first = [self objectAtIndex: 0];
		[self removeObjectAtIndex: 0];
		return first;
	} else {
		return nil;
	}
}

-(NSMutableArray*)push:(id)element
{
	[self addObject: element];
	return self;
}

-(id)pop
{
	NSUInteger count = [self count];
	if (count > 0) {
		id last = [self objectAtIndex: count - 1];
		[self removeLastObject];
		return last;
	} else {
		return nil;
	}
}
@end


@implementation NSString (Split)
-(NSMutableArray*)componentsSeparatedByCharacter:(unichar)separator
{
	return [NSMutableArray arrayWithArray: [self componentsSeparatedByString:[NSString stringWithFormat:@"%c", separator]]];
}

-(NSMutableArray*)numbersSeparatedByString:(NSString*)separator
{
	NSArray *strings = [self componentsSeparatedByString: separator];
	NSMutableArray *numbers = [NSMutableArray array];
	for (NSString *string in strings) {
		if (![string isEqualToString:@""]) {
			[numbers addObject: [NSNumber numberWithInteger: [string integerValue]]];
		}
	}
	return numbers;
}

-(NSMutableArray*)numbersSeparatedByCharacter:(unichar)separator
{
	return [self numbersSeparatedByString:[NSString stringWithFormat:@"%c", separator]];
}

-(NSMutableArray*)splitCharacterEvery:(NSUInteger)number
{
	if ([self length] <= number) {
		return [NSMutableArray arrayWithObject: self];
	}

	NSMutableArray  *mArray = [NSMutableArray array];
	NSMutableString *mStr   = [NSMutableString stringWithString: self];

	NSRange range = NSMakeRange(0, number);

	while ([mStr length] > 0) {
		if ([mStr length] < number) {
			[mArray addObject: [NSString stringWithString: mStr]];
			[mStr deleteCharactersInRange:NSMakeRange(0, [mStr length])];
		} else {
			[mArray addObject: [mStr substringWithRange: range]];
			[mStr deleteCharactersInRange: range];
		}
	}

	return mArray;
}

-(NSMutableArray*)characters {
	return [self splitCharacterEvery: 1];
}

-(unichar)firstCharacter
{
	return [self characterAtIndex: 0];
}

-(unichar)lastCharacter
{
	return [self characterAtIndex: [self length] - 1];
}

-(NSString*)leadingSubstringWithLength:(NSUInteger)length
{
	if (length <= [self length]) {
		return [self substringWithRange: NSMakeRange(0, length)];
	} else {
		return nil;
	}
	
}

-(NSString*)trailingSubstringWithLength:(NSUInteger)length
{
	NSUInteger mylength = [self length];
	if (length <= mylength) {
		return [self substringWithRange: NSMakeRange(mylength - length, length)];
	} else {
		return nil;
	}
}

@end

@implementation NSMutableString (List)
-(NSMutableString*)unshift:(NSString*)string
{
	[self insertString: string atIndex: 0];
	return self;
}

-(NSString*)shiftWithLength:(NSUInteger)length
{
	if ([self length] >= length) {
		NSRange range = NSMakeRange(0, length);
		NSString *first = [self substringWithRange: range];
		[self deleteCharactersInRange: range];
		return first;
	} else {
		return nil;
	}
}

-(NSString*)push:(NSString*)string
{
	[self appendString: string];
	return self;
}

-(NSString*)popWithLength:(NSUInteger)length
{
	NSUInteger mylength = [self length];
	if (length <= mylength) {
		NSRange range = NSMakeRange(mylength - length, length);
		NSString *last = [self substringWithRange: range];
		[self deleteCharactersInRange: range];
		return last;
	} else {
		return nil;
	}
}
@end

@implementation StdIO
+(NSMutableString*)stringFromStdIn
{
	NSFileHandle *handle = [NSFileHandle fileHandleWithStandardInput];
	NSMutableString *result = [NSMutableString string];
	NSData *data = [handle availableData];
	while ([data length] > 0) {
		[result appendString:[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]];
		data = [handle availableData];
	}

	if ([result lastCharacter] == '\n') {
		[result popWithLength: 1];
	}
	return result;
}

+(NSMutableArray*)stringsFromStdInSeparatedByString:(NSString*)separator
{
	return [NSMutableArray arrayWithArray:[[StdIO stringFromStdIn] componentsSeparatedByString: separator]];
}

+(NSMutableArray*)stringsFromStdInSeparatedByCharacter:(unichar)separator
{
	return [NSMutableArray arrayWithArray:[[StdIO stringFromStdIn] componentsSeparatedByCharacter: separator]];
}

+(NSMutableArray*)numbersFromStdInSeparatedByString:(NSString*)separator
{
	return [[StdIO stringFromStdIn] numbersSeparatedByString: separator];
}

+(NSMutableArray*)numbersFromStdInSeparatedByCharacter:(unichar)separator
{
	return [[StdIO stringFromStdIn] numbersSeparatedByCharacter: separator];
}

+(void)putsToStdOut:(NSString*)string
{
	NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
	[fileHandle writeData:[string dataUsingEncoding: NSUTF8StringEncoding]];
	[fileHandle writeData:[@"\n" dataUsingEncoding: NSUTF8StringEncoding]];
}

+(void)put:(char*)format, ...
{
	va_list arguments;
	va_start(arguments, format);
	NSString *string = [[NSString alloc] initWithFormat: [NSString stringWithUTF8String: format] arguments: arguments];
	[StdIO putsToStdOut: string];
	va_end(arguments);	
}

+(void)puts:(NSString*)format, ...
{
	va_list arguments;
	va_start(arguments, format);
	NSString *string = [[NSString alloc] initWithFormat: format arguments: arguments];
	[StdIO putsToStdOut: string];
	va_end(arguments);	
}
@end

/////////////////////////////////////////////////////////////////////////////////

int main(int argc, const char * argv[]) {
	@autoreleasepool {
				NSMutableArray *numbers = [StdIO numbersFromStdInSeparatedByCharacter:' '];
				NSInteger a = [numbers firstInteger];
				NSInteger b = [numbers secondInteger];
				NSInteger c = [numbers thirdInteger];
				if (a==b) [StdIO put: "%ld", c];
				if (c==b) [StdIO put: "%ld", a];
				if (a==c) [StdIO put: "%ld", b];
	}
	return 0;
}

Measured memory_bytes: 2404