You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.8 KiB
Swift
156 lines
5.8 KiB
Swift
//
|
|
// 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)")
|
|
}
|
|
}
|