How to solve HackerRank problems in Objective-C

#import <Foundation/Foundation.h> 

int sum(int a, int b) {
   return a + b;
}

int main() {
   @autoreleasepool {
      int T;
      int A;
      int B;
      printf("Enter number of test cases: ");
      scanf("%d", &T);
      for (int i=0; i < T; i++) {
          scanf("%d", &A);
          scanf("%d", &B);
          printf("%d\n", sum(A,B));
      }
     }
   return 0;
}

That ought to do it.


Having just been handed one of these tests, I opted to get out of main.m immediately and into Objective-C like so:

#import <Foundation/Foundation.h>

//Objective-C helper class to take over from main.m

//.h
@interface MainClass : NSObject

+ (BOOL)startMain;

@end

//.m
@implementation MainClass

+ (BOOL)startMain {

    //Read the STDIN here using the Objective-C wrapper methods
    NSInteger n = [self readInt];

    [self printInt:n];

    NSArray *numbers = [self readIntArrayOfLength:n];

    [self printIntNumberArray:numbers];

    return YES;
}

+ (NSInteger)readInt {

    int n;

    scanf("%i",&n);

    return n;
}

+ (NSArray *)readIntArrayOfLength:(NSInteger)len {

    NSMutableArray *result = [NSMutableArray array];

    for (int i =0; i < len; i++) {

        [result addObject:[NSNumber numberWithInt:[self readInt]]];
    }

    return [result copy];
}

//Helpers to print an int and array of ints to STDOUT
+ (void)printInt:(NSInteger)i {

    printf("%li\n",(long)i);
}

+ (void)printIntNumberArray:(NSArray *)array {

    printf("[");

    [array enumerateObjectsUsingBlock:^(NSNumber *n, NSUInteger idx, BOOL * _Nonnull stop) {

        printf("%li",(long)[n integerValue]);

        if (idx < array.count-1) {
            printf(",");
        }
    }];

    printf("]\n");
}

@end

//This is what will actually run when you hit "Run Code"
int main(int argc, char * argv[]) {

    @autoreleasepool {
        return [MainClass startMain];
    }
}

Now you can do whatever you like from here using Objective-C.

So in this example a sample input of:

3
11 2 4

Would produce this output:

3
[11,2,4]

Not useful in of itself but illustrates the successful read.

It's a lot simpler in Swift, but here's code to accomplish the same thing anyway:

func readInt() -> Int? {

    if let ln = readLine() {
        return Int(ln)
    }

    return nil
}

func readIntArray() -> [Int]? {

     if let ln = readLine() {

        return ln.characters.split(" ").filter({ Int(String($0)) != nil }).map({ Int(String($0))! })
    }

    return nil
}

let n = readInt()!
let array = readIntArray()!

print(n)
print(array)

The functions return optionals because even though you are going to force-unwrap the input, better the crash for a nil optional happens in your code than the boilerplate.


The simplest possible way to "Read input from STDIN. Print output to STDOUT" would be to use scanf and printf.
Here's a sample template to get you started:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    int count;
    scanf("%d", &count);
    NSMutableArray *inputIntegers = [NSMutableArray new];

    for (int i=0; i<count; i++) {
        int inputElement;
        scanf("%d", &inputElement);
        [inputIntegers addObject:[NSNumber numberWithInt:inputElement]];
    }

    //to print a specific element:
    printf("printing element 0: %d", (int)[inputIntegers[0] integerValue]);

    [pool drain];
    return 0;
}

Before you take a shot at this journey, a few things:

  • Make sure ARC is disabled (search for CLANG_ENABLE_OBJC_ARC in build settings, and set it to NO)
  • Avoid using self. This is functional programming.
  • Use C functions, not Objective-C methods, meaning, use

instead of

 - (NSInteger)sumOfNumbers : (NSInteger)a and:(NSInteger)b {
    return a + b;
}

use

int sumOfNumbers(int a, int b){

    return a + b;
}

Happy Programming.

Tags:

Objective C