Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All Your Base exercise #161

Merged
merged 1 commit into from
Jul 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,14 @@
,"triangle"
,"scrabble-score"
,"roman-numerals"
,"binary"
,"prime-factors"
,"raindrops"
,"bob"
,"strain"
,"atbash-cipher"
,"crypto-square"
,"trinary"
,"rna-transcription"
,"sieve"
,"octal"
,"luhn"
,"series"
,"pig-latin"
Expand All @@ -57,7 +54,6 @@
,"queen-attack"
,"binary-search"
,"binary-search-tree"
,"hexadecimal"
,"largest-series-product"
,"matrix"
,"house"
Expand All @@ -69,9 +65,13 @@
,"saddle-points"
,"poker"
,"dominoes"
,"all-your-base"
],
"deprecated": [

"binary"
,"trinary"
,"octal"
,"hexadecimal"
],
"ignored": [
"docs",
Expand Down
59 changes: 59 additions & 0 deletions exercises/all-your-base/AllYourBaseExample.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
enum BaseError: ErrorProtocol {
case invalidInputBase
case invalidOutputBase
case negativeDigit
case invalidPositiveDigit
}

struct Base {

static func outputDigits(inputBase: Int, inputDigits: [Int], outputBase: Int) throws -> [Int] {
guard inputBase >= 2 else {
throw BaseError.invalidInputBase
}

guard outputBase >= 2 else {
throw BaseError.invalidOutputBase
}

let sum = try getSum(digits: inputDigits, base: inputBase)
let result = getDigits(sum: sum, base: outputBase)

return result
}

private static func getSum(digits: [Int], base: Int) throws -> Int {
var multiplier = 1
var sum = 0

for digit in digits.reversed() {
guard digit >= 0 else {
throw BaseError.negativeDigit
}
guard digit < base else {
throw BaseError.invalidPositiveDigit
}

sum += digit * multiplier
multiplier *= base
}

return sum
}

private static func getDigits(sum: Int, base: Int) -> [Int] {
var sum = sum
var digits = [Int]()
var multiplier = 1

while sum > 0 {
multiplier *= base
let value = sum % multiplier
let digit = value / (multiplier / base)
digits.append(digit)
sum -= value
}

return digits.reversed()
}
}
103 changes: 103 additions & 0 deletions exercises/all-your-base/AllYourBaseTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#if swift(>=3.0)
import XCTest
#endif

class AllYourBaseTest: XCTestCase {

func errorThrown<T, U: ErrorProtocol>(byExpression expression: @autoclosure () throws -> T) -> U? {
do {
let _ = try expression()
return nil
} catch {
return error as? U
}
}

func testSingleBitOneToDecimal() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 2, inputDigits: [1], outputBase: 10), [1])
}

func testBinaryToSingleDecimal() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 2, inputDigits: [1, 0, 1], outputBase: 10), [5])
}

func testSingleDecimalToBinary() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 10, inputDigits: [5], outputBase: 2), [1, 0, 1])
}

func testBinaryToMultipleDecimal() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 2, inputDigits: [1, 0, 1, 0, 1, 0], outputBase: 10), [4, 2])
}

func testDecimalToBinary() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 10, inputDigits: [4, 2], outputBase: 2), [1, 0, 1, 0, 1, 0])
}

func testTrinaryToHexadecimal() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 3, inputDigits: [1, 1, 2, 0], outputBase: 16), [2, 10])
}

func testHexadecimalToTrinary() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 16, inputDigits: [2, 10], outputBase: 3), [1, 1, 2, 0])
}

func test15BitInteger() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 97, inputDigits: [3, 46, 60], outputBase: 73), [6, 10, 45])
}

func testEmptyList() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 2, inputDigits: [], outputBase: 10), [])
}

func testSingleZero() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 10, inputDigits: [0], outputBase: 2), [])
}

func testMultipleZeros() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 10, inputDigits: [0, 0, 0], outputBase: 2), [])
}

func testLeadingZeros() {
XCTAssertEqual(try! Base.outputDigits(inputBase: 7, inputDigits: [0, 6, 0], outputBase: 10), [4, 2])
}

func testNegativeDigit() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 2, inputDigits: [1, -1, 1, 0, 1, 0], outputBase: 10))
XCTAssertTrue(error == .negativeDigit)
}

func testInvalidPositiveDigit() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 2, inputDigits: [1, 2, 1, 0, 1, 0], outputBase: 10))
XCTAssertTrue(error == .invalidPositiveDigit)
}

func testFirstBaseIsOne() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 1, inputDigits: [], outputBase: 10))
XCTAssertTrue(error == .invalidInputBase)
}

func testSecondBaseIsOne() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 2, inputDigits: [1, 0, 1, 0, 1, 0], outputBase: 1))
XCTAssertTrue(error == .invalidOutputBase)
}

func testFirstBaseIsZero() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 0, inputDigits: [], outputBase: 10))
XCTAssertTrue(error == .invalidInputBase)
}

func testSecondBaseIsZero() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 10, inputDigits: [7], outputBase: 0))
XCTAssertTrue(error == .invalidOutputBase)
}

func testFirstBaseIsNegative() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: -2, inputDigits: [1], outputBase: 10))
XCTAssertTrue(error == .invalidInputBase)
}

func testSecondBaseIsNegative() {
let error: BaseError? = errorThrown(byExpression: try Base.outputDigits(inputBase: 2, inputDigits: [1], outputBase: -7))
XCTAssertTrue(error == .invalidOutputBase)
}
}
17 changes: 17 additions & 0 deletions xcodeProject/xSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@
E90D62001C642EFB00C266D3 /* OcrNumbersTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90D61FF1C642EFB00C266D3 /* OcrNumbersTest.swift */; };
E90D62061C653AC000C266D3 /* PalindromeProductsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90D62051C653AC000C266D3 /* PalindromeProductsExample.swift */; };
E90D62081C653ADC00C266D3 /* PalindromeProductsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90D62071C653ADC00C266D3 /* PalindromeProductsTest.swift */; };
E90DE39C1D3E812300F3B881 /* AllYourBaseExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90DE39B1D3E812300F3B881 /* AllYourBaseExample.swift */; };
E90DE39E1D3E818000F3B881 /* AllYourBaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90DE39D1D3E818000F3B881 /* AllYourBaseTest.swift */; };
E94BDECF1C510E68009318BB /* BinarySearchExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94BDECD1C510E68009318BB /* BinarySearchExample.swift */; };
E94BDED01C510E68009318BB /* BinarySearchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94BDECE1C510E68009318BB /* BinarySearchTest.swift */; };
E9AFA1481C593AF5006AD72D /* BinarySearchTreeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9AFA1461C593AF5006AD72D /* BinarySearchTreeExample.swift */; };
Expand Down Expand Up @@ -273,6 +275,8 @@
E90D61FF1C642EFB00C266D3 /* OcrNumbersTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = OcrNumbersTest.swift; path = "ocr-numbers/OcrNumbersTest.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
E90D62051C653AC000C266D3 /* PalindromeProductsExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PalindromeProductsExample.swift; path = "palindrome-products/PalindromeProductsExample.swift"; sourceTree = "<group>"; };
E90D62071C653ADC00C266D3 /* PalindromeProductsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = PalindromeProductsTest.swift; path = "palindrome-products/PalindromeProductsTest.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
E90DE39B1D3E812300F3B881 /* AllYourBaseExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AllYourBaseExample.swift; path = "../all-your-base/AllYourBaseExample.swift"; sourceTree = "<group>"; };
E90DE39D1D3E818000F3B881 /* AllYourBaseTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AllYourBaseTest.swift; path = "../all-your-base/AllYourBaseTest.swift"; sourceTree = "<group>"; };
E94BDECD1C510E68009318BB /* BinarySearchExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinarySearchExample.swift; path = "binary-search/BinarySearchExample.swift"; sourceTree = "<group>"; };
E94BDECE1C510E68009318BB /* BinarySearchTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = BinarySearchTest.swift; path = "binary-search/BinarySearchTest.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
E9AFA1461C593AF5006AD72D /* BinarySearchTreeExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = BinarySearchTreeExample.swift; path = "binary-search-tree/BinarySearchTreeExample.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
Expand Down Expand Up @@ -314,6 +318,7 @@
children = (
1E9A62E91C506EFC00E28AE1 /* accumulate */,
1E9A62EC1C506EFC00E28AE1 /* acronym */,
E90DE3991D3E80F700F3B881 /* all-your-base */,
1E9A62EF1C506EFC00E28AE1 /* allergies */,
1E9A62F21C506EFC00E28AE1 /* anagram */,
1E9A62F51C506EFC00E28AE1 /* atbash-cipher */,
Expand Down Expand Up @@ -948,6 +953,16 @@
name = "palindrome-products";
sourceTree = "<group>";
};
E90DE3991D3E80F700F3B881 /* all-your-base */ = {
isa = PBXGroup;
children = (
E90DE39B1D3E812300F3B881 /* AllYourBaseExample.swift */,
E90DE39D1D3E818000F3B881 /* AllYourBaseTest.swift */,
);
name = "all-your-base";
path = acronym;
sourceTree = "<group>";
};
E94BDECB1C510DF4009318BB /* binary-search */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1178,12 +1193,14 @@
1E167A111C8AA5D7001EAD90 /* PokerExample.swift in Sources */,
1E9A639E1C506EFD00E28AE1 /* EtlExample.swift in Sources */,
1EAF95E11C90C587009DDCB6 /* DominoesTest.swift in Sources */,
E90DE39C1D3E812300F3B881 /* AllYourBaseExample.swift in Sources */,
1E9A63CE1C506EFD00E28AE1 /* RobotSimulatorExample.swift in Sources */,
1E9A639D1C506EFD00E28AE1 /* DifferenceOfSquaresTest.swift in Sources */,
E9AFA1531C5945C9006AD72D /* HexadecimalTest.swift in Sources */,
1E9A63AF1C506EFD00E28AE1 /* LeapTest.swift in Sources */,
1E9A63901C506EFD00E28AE1 /* AtbashExample.swift in Sources */,
1E9A63C61C506EFD00E28AE1 /* QueenAttackExample.swift in Sources */,
E90DE39E1D3E818000F3B881 /* AllYourBaseTest.swift in Sources */,
E908CD481C6AD076005D081E /* FoodChainTest.swift in Sources */,
1E9A63D91C506EFD00E28AE1 /* SieveTest.swift in Sources */,
1E9A63AA1C506EFD00E28AE1 /* helloWorldTest.swift in Sources */,
Expand Down