// // Advent of Code 2018 "Day 1: Chronal Calibration" // import Foundation class Chronal { fileprivate var adjustments: [Int] = [] let startingFreq = 0 // Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day01.txt' init(withFile filename: String) { let adjString = Tools.readFile(fromPath: filename) var adjustmentArray: [String] = [] adjustmentArray = adjString.components(separatedBy: "\n") adjustments = [] for val in adjustmentArray { if let intVal = Int(val) { adjustments.append(intVal) } } } // Supply test data in the form of a String init(withString adjString: String) { var adjustmentArray: [String] = [] adjustmentArray = adjString.components(separatedBy: ", ") adjustments = [] for val in adjustmentArray { if let intVal = Int(val) { adjustments.append(intVal) } } } // Apply all the adjustments that this class was initialized with // Return the resulting frequency as an Optional (nil => no adjustments) func applyAdjustments() -> Int? { var retVal: Int? if adjustments.count > 0 { var sum = 0 for val in adjustments { sum += val } retVal = sum } return retVal } func repeatedAjustmentUntilTwice() -> Int { var retVal = -1 if adjustments.count > 0 { var usedFreqs = [Int: Int]() var sum = 0 usedFreqs[sum] = 1 var noRepeats = true repeat { for val in adjustments { sum += val if usedFreqs[sum] != nil { retVal = sum noRepeats = false break } else { usedFreqs[sum] = 1 } } } while noRepeats } return retVal } } class Day01: AOCDay { lazy var tests: (() -> ()) = day01Tests lazy var final: (() -> ()) = day01Final func testInitWithFile() { let chrona = Chronal(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day01.txt") XCTAssertEqual(test: "testInitWithFile", withExpression: (chrona.adjustments.count == 990)) if chrona.adjustments.count == 990 { XCTAssertEqual(test: "testInitWithFile index[10]", withExpression: (chrona.adjustments[10] == -17)) XCTAssertEqual(test: "testInitWithFile index[989]", withExpression: (chrona.adjustments[989] == 124726)) } } // +1, +1, +1 results in 3 // +1, +1, -2 results in 0 // -1, -2, -3 results in -6 func testInitWithString() { var chrona = Chronal(withString: "+1, +1, +1") XCTAssertEqual(test: "testInitWithString", withExpression: (chrona.adjustments.count == 3)) if chrona.adjustments.count == 3 { XCTAssertEqual(test: "testInitWithString index[1]", withExpression: (chrona.adjustments[1] == 1)) } chrona = Chronal(withString: "+1, +1, -2") XCTAssertEqual(test: "testInitWithString", withExpression: (chrona.adjustments.count == 3)) if chrona.adjustments.count == 3 { XCTAssertEqual(test: "testInitWithString index[1]", withExpression: (chrona.adjustments[1] == 1)) } chrona = Chronal(withString: "-1, -2, -3") XCTAssertEqual(test: "testInitWithString", withExpression: (chrona.adjustments.count == 3)) if chrona.adjustments.count == 3 { XCTAssertEqual(test: "testInitWithString index[1]", withExpression: (chrona.adjustments[1] == -2)) } } func testApplyAdjustments() { var chrona = Chronal(withString: "+1, +1, +1") var val = chrona.applyAdjustments() XCTAssertEqual(test: "testApplyAdjustments", withExpression: (val == 3)) chrona = Chronal(withString: "+1, +1, -2") val = chrona.applyAdjustments() XCTAssertEqual(test: "testApplyAdjustments", withExpression: (val == 0)) chrona = Chronal(withString: "-1, -2, -3") val = chrona.applyAdjustments() XCTAssertEqual(test: "testApplyAdjustments", withExpression: (val == -6)) } // +1, -1 first reaches 0 twice. // +3, +3, +4, -2, -4 first reaches 10 twice. // -6, +3, +8, +5, -6 first reaches 5 twice. // +7, +7, -2, -7, -4 first reaches 14 twice. func testRepeatedAjustmentUntilTwice() { var chrona = Chronal(withString: "+1, -1") var val = chrona.repeatedAjustmentUntilTwice() XCTAssertEqual(test: "testRepeatedAjustmentUntilTwice", withExpression: (val == 0)) chrona = Chronal(withString: "+3, +3, +4, -2, -4") val = chrona.repeatedAjustmentUntilTwice() XCTAssertEqual(test: "testRepeatedAjustmentUntilTwice", withExpression: (val == 10)) chrona = Chronal(withString: "-6, +3, +8, +5, -6") val = chrona.repeatedAjustmentUntilTwice() XCTAssertEqual(test: "testRepeatedAjustmentUntilTwice", withExpression: (val == 5)) chrona = Chronal(withString: "+7, +7, -2, -7, -4") val = chrona.repeatedAjustmentUntilTwice() XCTAssertEqual(test: "testRepeatedAjustmentUntilTwice", withExpression: (val == 14)) } func day01Tests() { testInitWithFile() testInitWithString() testApplyAdjustments() testRepeatedAjustmentUntilTwice() } func day01Final() { let chrona = Chronal(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day01.txt") if let val = chrona.applyAdjustments() { print("Answer to part 1 is: \(val)") } let twice = chrona.repeatedAjustmentUntilTwice() print("Answer to part 2 is: \(twice)") } }