diff --git a/Sources/AOC2018/day07.swift b/Sources/AOC2018/day07.swift index 78f438a..54779f3 100644 --- a/Sources/AOC2018/day07.swift +++ b/Sources/AOC2018/day07.swift @@ -17,12 +17,26 @@ struct Instruction: Equatable, Comparable { } } +struct Worker: Equatable, Comparable { + var job = Character(" ") + var duration = 0 + + static func == (lhs: Worker, rhs: Worker) -> Bool { + return (lhs.job == rhs.job) && (lhs.duration == rhs.duration) + } + + static func < (lhs: Worker, rhs: Worker) -> Bool { + return lhs.duration < rhs.duration + } +} + class SumParts { var instrList: [Instruction] = [] - var inventoryComplete: [Character] = [] + var workers: [Worker] = [] + var masterClock = 0 // Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day07.txt' - init(withFile filename: String) { + init(withFile filename: String, numWorkers: Int) { let instrString = Tools.readFile(fromPath: filename) var instrArray = instrString.components(separatedBy: "\n") // This gurd statement is just an excuse to use guard @@ -30,12 +44,14 @@ class SumParts { guard let lastStr = instrArray.last, lastStr.count == 0 else { return } instrArray.removeLast() // empty string parseData(withInstructions: instrArray) + workers = Array(repeating: Worker(), count: numWorkers) } // Supply test data in the form of a String - init(withString instrString: String) { + init(withString instrString: String, numWorkers: Int) { let instrArray = instrString.components(separatedBy: "\n") parseData(withInstructions: instrArray) + workers = Array(repeating: Worker(), count: numWorkers) } func parseData(withInstructions instr: [String]) { @@ -45,6 +61,7 @@ class SumParts { } func getNextAvailable() -> Character? { + var retVal: Character? var availDict: [Character : Bool] = [:] for index in 0.. String { + func completeAllInstructions() -> String { var retVal = "" var last: Character = "*" while let instruction = getNextAvailable() { @@ -69,6 +98,77 @@ class SumParts { retVal.append(last) return retVal } + + func complete(instruction: Character) { + if instrList.count == 1 && instrList[0].complete != " " { + instrList.append(Instruction(complete: instrList[0].before, before: Character(" "))) + } + instrList.removeAll(where: { $0.complete == instruction }) + } + +//-------------->> Code for Part 2 <<-------------- + + // We'll cheat here and assume the duration is 1 second + offset for One worker and 60 seconds + offset for more than one + func duration(forInstruction instr: Character) -> Int { + guard let val = instr.ascii else { return -1 } + let offset = Int(val) - 64 + return (workers.count > 2) ? 60 + offset : offset + } + + // Go through the list of workers and find the min() time-to-finish + func getTimeUntilWorkerFree() -> Int { + guard workers.count > 0 else { return 0 } + let sortedByDuration = workers.sorted(by: { $0.duration < $1.duration }) + for worker in sortedByDuration { + if worker.duration != 0 { + return worker.duration + } + } + return 0 + } + + func advanceTime(by elapsedtime: Int) { + for index in 0.. 0 { + workers[index].duration -= elapsedtime + } + } + masterClock += elapsedtime + } + + // subtract XX seconds from the workers time and add that to the master-clock + // Since we advance until worker(s) done, we should complete the tasks finsished by the worker(s) + // return true if more work to do + func advanceClockAndCompleteInstructions() -> Bool { + guard workers.count > 0 else { return false } + let advTime = getTimeUntilWorkerFree() + if advTime == 0 { + let test = workers.contains(where: { $0.duration != 0} ) + if !test { + return false + } + } + // subtract this time from all workers + // add this time to the Master-Clock + advanceTime(by: advTime) + // Complete the "finished" worker(s) instruction + for index in 0.. ())] = [] var allFinal: [(() -> ())] = []