diff --git a/config.json b/config.json index 8e5ff36..6f8aa2c 100755 --- a/config.json +++ b/config.json @@ -17,6 +17,7 @@ ,"etl" ,"perfect-numbers" ,"space-age" + ,"all-your-base" ], "deprecated": [ diff --git a/exercises/all-your-base/AllYourBaseExample.h b/exercises/all-your-base/AllYourBaseExample.h new file mode 100644 index 0000000..7b23668 --- /dev/null +++ b/exercises/all-your-base/AllYourBaseExample.h @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +@interface AllYourBase : NSObject + ++ (NSArray<NSNumber *> *)outputDigitsForInputBase:(int)inputBase inputDigits:(NSArray<NSNumber *> *)inputDigits outputBase:(int)outputBase; + +@end diff --git a/exercises/all-your-base/AllYourBaseExample.m b/exercises/all-your-base/AllYourBaseExample.m new file mode 100644 index 0000000..45689f7 --- /dev/null +++ b/exercises/all-your-base/AllYourBaseExample.m @@ -0,0 +1,58 @@ +#import <Foundation/Foundation.h> +#import "AllYourBaseExample.h" + +@implementation AllYourBase + ++ (NSArray<NSNumber *> *)outputDigitsForInputBase:(int)inputBase inputDigits:(NSArray<NSNumber *> *)inputDigits outputBase:(int)outputBase { + + if (inputBase < 2) { + @throw [NSException exceptionWithName:@"Invalid input base" reason:@"Less than 2" userInfo:nil]; + } + + if (outputBase < 2) { + @throw [NSException exceptionWithName:@"Invalid output base" reason:@"Less than 2" userInfo:nil]; + } + + int sum = [self getSumForDigits:inputDigits andBase:inputBase]; + return [self getDigitsForSum:sum andBase:outputBase]; +} + ++ (int)getSumForDigits:(NSArray<NSNumber *> *)digits andBase:(int)base { + int multiplier = 1; + int sum = 0; + + for (NSNumber *digit in [[digits reverseObjectEnumerator] allObjects]) { + int digitValue = [digit intValue]; + + if (digitValue < 0) { + @throw [NSException exceptionWithName:@"Invalid digit" reason:@"Negative value" userInfo:nil]; + } + + if (digitValue >= base) { + @throw [NSException exceptionWithName:@"Invalid digit" reason:@"Too high for base" userInfo:nil]; + } + + sum += digitValue * multiplier; + multiplier *= base; + } + + return sum; +} + ++ (NSArray<NSNumber *> *)getDigitsForSum:(int)sum andBase:(int)base { + NSMutableArray<NSNumber *> *digits = [[NSMutableArray alloc] init]; + int multiplier = 1; + + while (sum > 0) { + multiplier *= base; + int value = sum % multiplier; + int digit = value / (multiplier / base); + [digits addObject:@(digit)]; + sum -= value; + } + + return [[digits reverseObjectEnumerator] allObjects]; +} + +@end + diff --git a/exercises/all-your-base/AllYourBaseTest.m b/exercises/all-your-base/AllYourBaseTest.m new file mode 100644 index 0000000..233bf7e --- /dev/null +++ b/exercises/all-your-base/AllYourBaseTest.m @@ -0,0 +1,127 @@ +#import <XCTest/XCTest.h> + +#if __has_include("AllYourBaseExample.h") +# import "AllYourBaseExample.h" +# else +# import "AllYourBase.h" +#endif + +@interface AllYourBaseTest : XCTestCase + +@end + +@implementation AllYourBaseTest + +- (void)testSingleBitOneToDecimal { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:2 inputDigits:@[@1] outputBase:10]; + NSArray<NSNumber *> *expected = @[@1]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testBinaryToSingleDecimal { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:2 inputDigits:@[@1, @0, @1] outputBase:10]; + NSArray<NSNumber *> *expected = @[@5]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testSingleDecimalToBinary { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:10 inputDigits:@[@5] outputBase:2]; + NSArray<NSNumber *> *expected = @[@1, @0, @1]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testBinaryToMultipleDecimal { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:2 inputDigits:@[@1, @0, @1, @0, @1, @0] outputBase:10]; + NSArray<NSNumber *> *expected = @[@4, @2]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testDecimalToBinary { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:10 inputDigits:@[@4, @2] outputBase:2]; + NSArray<NSNumber *> *expected = @[@1, @0, @1, @0, @1, @0]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testTrinaryToHexadecimal { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:3 inputDigits:@[@1, @1, @2, @0] outputBase:16]; + NSArray<NSNumber *> *expected = @[@2, @10]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testHexadecimalToTrinary { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:16 inputDigits:@[@2, @10] outputBase:3]; + NSArray<NSNumber *> *expected = @[@1, @1, @2, @0]; + XCTAssertEqualObjects(result, expected); +} + +- (void)test15BitInteger { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:97 inputDigits:@[@3, @46, @60] outputBase:73]; + NSArray<NSNumber *> *expected = @[@6, @10, @45]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testEmptyList { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:2 inputDigits:@[] outputBase:10]; + NSArray<NSNumber *> *expected = @[]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testSingleZero { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:10 inputDigits:@[@0] outputBase:2]; + NSArray<NSNumber *> *expected = @[]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testMultipleZeros { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:10 inputDigits:@[@0, @0, @0] outputBase:2]; + NSArray<NSNumber *> *expected = @[]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testLeadingZeros { + NSArray<NSNumber *> *result = [AllYourBase outputDigitsForInputBase:7 inputDigits:@[@0, @6, @0] outputBase:10]; + NSArray<NSNumber *> *expected = @[@4, @2]; + XCTAssertEqualObjects(result, expected); +} + +- (void)testNegativeDigit { + NSArray<NSNumber *> *inputDigits = @[@1, @(-1), @1, @0, @1, @0]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:2 inputDigits:inputDigits outputBase:10]); +} + +- (void)testInvalidPositiveDigit { + NSArray<NSNumber *> *inputDigits = @[@1, @2, @1, @0, @1, @0]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:2 inputDigits:inputDigits outputBase:10]); +} + +- (void)testFirstBaseIsOne { + NSArray<NSNumber *> *inputDigits = @[]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:1 inputDigits:inputDigits outputBase:10]); +} + +- (void)testSecondBaseIsOne { + NSArray<NSNumber *> *inputDigits = @[@1, @0, @1, @0, @1, @0]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:2 inputDigits:inputDigits outputBase:1]); +} + +- (void)testFirstBaseIsZero { + NSArray<NSNumber *> *inputDigits = @[]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:0 inputDigits:inputDigits outputBase:10]); +} + +- (void)testSecondBaseIsZero { + NSArray<NSNumber *> *inputDigits = @[@7]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:10 inputDigits:inputDigits outputBase:0]); +} + +- (void)testFirstBaseIsNegative { + NSArray<NSNumber *> *inputDigits = @[@1]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:-2 inputDigits:inputDigits outputBase:10]); +} + +- (void)testSecondBaseIsNegative { + NSArray<NSNumber *> *inputDigits = @[@1]; + XCTAssertThrows([AllYourBase outputDigitsForInputBase:2 inputDigits:inputDigits outputBase:-7]); +} + +@end diff --git a/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj b/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj index 4242a47..c4b660d 100755 --- a/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +++ b/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj @@ -33,6 +33,8 @@ 1EFACABA1CCCAF3D006F2E69 /* SpaceAgeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EFACA9F1CCCAF3D006F2E69 /* SpaceAgeTest.m */; }; 1EFACABB1CCCAF3D006F2E69 /* WordCountExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EFACAA11CCCAF3D006F2E69 /* WordCountExample.m */; }; 1EFACABC1CCCAF3D006F2E69 /* WordCountTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EFACAA21CCCAF3D006F2E69 /* WordCountTest.m */; }; + E94ACA131D41760300D56CC2 /* AllYourBaseExample.m in Sources */ = {isa = PBXBuildFile; fileRef = E94ACA121D41760300D56CC2 /* AllYourBaseExample.m */; }; + E94ACA151D41763800D56CC2 /* AllYourBaseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E94ACA141D41763800D56CC2 /* AllYourBaseTest.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -77,6 +79,9 @@ 1EFACAA01CCCAF3D006F2E69 /* WordCountExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WordCountExample.h; path = "../../exercises/word-count/WordCountExample.h"; sourceTree = "<group>"; }; 1EFACAA11CCCAF3D006F2E69 /* WordCountExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WordCountExample.m; path = "../../exercises/word-count/WordCountExample.m"; sourceTree = "<group>"; }; 1EFACAA21CCCAF3D006F2E69 /* WordCountTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WordCountTest.m; path = "../../exercises/word-count/WordCountTest.m"; sourceTree = "<group>"; }; + E94ACA111D4175C600D56CC2 /* AllYourBaseExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AllYourBaseExample.h; path = "../../exercises/all-your-base/AllYourBaseExample.h"; sourceTree = "<group>"; }; + E94ACA121D41760300D56CC2 /* AllYourBaseExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AllYourBaseExample.m; path = "../../exercises/all-your-base/AllYourBaseExample.m"; sourceTree = "<group>"; }; + E94ACA141D41763800D56CC2 /* AllYourBaseTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AllYourBaseTest.m; path = "../../exercises/all-your-base/AllYourBaseTest.m"; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -93,6 +98,9 @@ 1E50BCFD1CB465C500FC128D /* xobjectivecTest */ = { isa = PBXGroup; children = ( + E94ACA111D4175C600D56CC2 /* AllYourBaseExample.h */, + E94ACA121D41760300D56CC2 /* AllYourBaseExample.m */, + E94ACA141D41763800D56CC2 /* AllYourBaseTest.m */, 1EFACA7C1CCCAF3D006F2E69 /* AnagramExample.h */, 1EFACA7D1CCCAF3D006F2E69 /* AnagramExample.m */, 1EFACA7E1CCCAF3D006F2E69 /* AnagramTest.m */, @@ -221,6 +229,8 @@ files = ( 1EFACAA71CCCAF3D006F2E69 /* EtlExample.m in Sources */, 1EFACAA31CCCAF3D006F2E69 /* AnagramExample.m in Sources */, + E94ACA131D41760300D56CC2 /* AllYourBaseExample.m in Sources */, + E94ACA151D41763800D56CC2 /* AllYourBaseTest.m in Sources */, 1EFACAA41CCCAF3D006F2E69 /* AnagramTest.m in Sources */, 1EFACABC1CCCAF3D006F2E69 /* WordCountTest.m in Sources */, 1EFACAB11CCCAF3D006F2E69 /* NucleotideCountExample.m in Sources */,