Skip to content

Instantly share code, notes, and snippets.

@ryanwarsaw
Last active October 13, 2017 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanwarsaw/c678427d1282ed33aa7c6ae589b217fb to your computer and use it in GitHub Desktop.
Save ryanwarsaw/c678427d1282ed33aa7c6ae589b217fb to your computer and use it in GitHub Desktop.
struct LargeInt {
var digits: [Int8] = [];
/**
* Default constructor if we don't want to provide a value, this is removed when we create our own so we have to do this dummy method.
**/
init() {
digits.append(0);
}
/**
* Failable initializer that attempts to convert each String character into an Int8 value to build the LargeInt, or returns nil if it fails.
* This can fail for many reasons, including foreign symbols in the input (i.e. #$%^&*()!@-_=+) or characters, anything that can't be converted to an Int8 value.
**/
init?(_ value: String) {
for (_, character) in String(value).characters.enumerated() {
if (Int8(String(character)) != nil) {
digits.append(Int8(String(character))!);
} else {
return nil;
}
}
}
/**
* Compress the digits array back down into a String, and return the result as a string.
**/
func toString() -> String {
return digits.map(String.init).joined();
}
/**
* Operator overload for the + symbol, so we can do things like: LargeInt("99") + LargeInt("111").
**/
static func +(left: LargeInt, right: LargeInt) -> LargeInt {
// Bigger & Smaller aren't defined by the value they hold, rather the amount of "digits" within the total number.
let bigger: LargeInt;
let smaller: LargeInt;
if (left.digits.count > right.digits.count) {
bigger = left;
smaller = right;
} else {
bigger = right;
smaller = left;
}
let maxIndex = bigger.digits.count;
var result: [Int8] = [];
var carryOver: Bool = false;
for i in 0..<maxIndex {
var sum: Int8 = 0;
// If true, we need to carry over the one from the previous iteration.
if (carryOver) {
sum += 1;
carryOver = false;
}
// if the index is present in both numbers then we add, otherwise we copy the value into the result (Because we can't add it to a non-existent index).
if (smaller.digits.indices.contains((smaller.digits.count - 1) - i) && bigger.digits.indices.contains((maxIndex - 1) - i)) {
sum += bigger.digits[(maxIndex - 1) - i] + smaller.digits[(smaller.digits.count - 1) - i];
} else {
sum += bigger.digits[(maxIndex - 1) - i];
}
// If the number is longer than one digit long, trim it and set the "carryOver" boolean to true.
if (String(sum).characters.count != 1) {
sum = sum % 10;
carryOver = true;
}
result.append(sum);
}
// This is a special edge case for if the last digit (right-to-left) needs carried over. We reverse the result, so we just append "1" for the carry over.
if (carryOver) {
result.append(1);
carryOver = false;
}
// We're going to compress the array back down into a String and return a new instance of LargeInt with the result.
return LargeInt(result.reversed().map(String.init).joined())!;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment