diff --git a/Sources/AOC2018/day04.swift b/Sources/AOC2018/day04.swift index 31b82e6..991f533 100644 --- a/Sources/AOC2018/day04.swift +++ b/Sources/AOC2018/day04.swift @@ -27,11 +27,6 @@ struct Activity: Equatable, Comparable { } } -struct GuardMap { - var id = 0 - var sleepMap: [Bool] = Array(repeating: false, count: 60) -} - // Make some assumptions based on the fact that there is only on guard on duty per night // read in data @@ -42,7 +37,7 @@ struct GuardMap { // - create histogram and determine which minute he has slept through the most class Repose { var scheduleArray: [String] = [] - var sleepMapForGuardID: [Int : [Int]] = [:] // id : Array if ints, one for each hour; increment if asleep + var sleepMapForGuardID: [Int : [Int]] = [:] // dictionary of [id : Array of ints, one for each hour; increment if asleep] var activitiesForDay: [Int : [Activity]] = [:] // Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day04.txt' @@ -53,15 +48,14 @@ class Repose { // I'm assuming the last string is an empty string, if not DON'T remove the last string guard let lastStr = scheduleArray.last, lastStr.count == 0 else { return } scheduleArray.removeLast() // empty string - // parseData(withSchedule: scheduleArray) } // Supply test data in the form of a String init(withString schedule: String) { scheduleArray = schedule.components(separatedBy: "\n") - // parseData(withSchedule: scheduleArray) - } + } + // Needed this due to Guard starting day before midnight of the previous month (broke my simple day = month * 31 rule) static func increment(day: Int) -> Int { // there is a leap year every year divisible by four except for years which are both divisible by 100 and not divisible by 400. // Therefore, the year 2000 will be a leap year, but the years 1700, 1800, and 1900 were not. @@ -74,13 +68,11 @@ class Repose { myDay = 31 myMonth -= 1 } - // print("input Day = \(day), myMonth=\(myMonth), myDay=\(myDay)") if myDay == nDays[myMonth - 1] { retVal = (myMonth + 1) * 31 + 1 } else { retVal = day + 1 } - // print("newDay = \(retVal)") return retVal } @@ -91,7 +83,6 @@ class Repose { if line.count > 0 { // Split line into time and action var parseString = line - // print("\n\(line)") parseString.removeFirst() let splitStr = parseString.components(separatedBy: "]") guard splitStr.count > 1 else { break parseScope } @@ -127,14 +118,12 @@ class Repose { startShiftStr.removeFirst() retVal.id = Int(startShiftStr.components(separatedBy: " ")[0]) ?? -1 } - // print("source line : \(retVal.day) \(hour) : \(retVal.minute) -- splitStr '\(actionStr)'\n") } return retVal } func add(activity: Activity) { if activitiesForDay[activity.day] == nil { - // print("adding day \(activity.day) activity : \(activity)") activitiesForDay[activity.day] = [activity] } else { activitiesForDay[activity.day]!.append(activity) @@ -149,7 +138,6 @@ class Repose { for day in activitiesForDay.keys { activitiesForDay[day]!.sort() sleepMapForGuardID[findID(forDay: day)] = Array(repeating: 0, count: 60) - // print("\(activitiesForDay[day]!)\n") } } } @@ -165,8 +153,6 @@ class Repose { func buildHistogram(forDay day: Int) -> [Int] { var retVal = Array(repeating: 0, count: 60) - // var sleepMapForGuardID: [Int : [Int]] = [:] // id : Array if ints, one for each hour; increment if asleep - // var activitiesForDay: [Int : [Activity]] = [:] addActivitiesIfNecessary() if let array = activitiesForDay[day] { var startSleep = 0 @@ -180,7 +166,6 @@ class Repose { retVal[min] = 1 } } - // print("\(activity)") } } return retVal @@ -197,19 +182,19 @@ class Repose { } // Sum all the minutes slept, retrun the total and the minute of most sleeps - func sumMinutes(forID id: Int) -> (total: Int, maxMinute: Int) { - var retVal = (total: 0, maxMinute: -1) + func sumMinutes(forID id: Int) -> (total: Int, maxMinute: Int, maxMinuteVal: Int) { + var retVal = (total: 0, maxMinute: -1, maxMinuteVal: -1) guard var array = sleepMapForGuardID[id] else { return retVal } guard array.count == 60 else { return retVal } for i in 0..<60 { retVal.total += array[i] } - retVal.maxMinute = array.firstIndex(of: (array.max() ?? 1)) ?? 0 - // print("ID:\(id), retVal:\(retVal)") + retVal.maxMinuteVal = array.max() ?? 1 + retVal.maxMinute = array.firstIndex(of: retVal.maxMinuteVal) ?? 0 return retVal } - func findGuard() -> (id: Int, minute: Int) { + func findGuard(forPart1 part1: Bool) -> (id: Int, minute: Int) { var retVal = (id: 0, minute: -1) addActivitiesIfNecessary() for day in activitiesForDay.keys { @@ -219,18 +204,16 @@ class Repose { var maxTime = 0 for id in sleepMapForGuardID.keys { let stats = sumMinutes(forID: id) - if stats.total > maxTime { - maxTime = stats.total + let maxForPart = part1 ? stats.total : stats.maxMinuteVal + if maxForPart > maxTime { + maxTime = maxForPart retVal.minute = stats.maxMinute retVal.id = id } } return retVal } - -// [1518-04-04 23:59] Guard #223 begins shift -// [1518-09-15 00:12] falls asleep -// [1518-06-01 00:32] wakes up +} // Need a state-machine // - start shift @@ -246,7 +229,6 @@ class Repose { // 11-04 #99 ....................................##########.............. // 11-05 #99 .............................................##########..... // #99 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,3,2,2,2,2,1,1,1,1,1,0,0,0,0,0 -} class Day04: AOCDay { lazy var tests: (() -> ()) = day04Tests @@ -306,7 +288,6 @@ class Day04: AOCDay { func testPasrseLine() { var response = Repose.parse(line: "") - // print("Response : \(response)") XCTAssertEqual(test: "testPasrseLine empty", withExpression: (response.minute == -1)) let repo = Repose(withString: testData) response = Repose.parse(line: repo.scheduleArray[0]) @@ -334,13 +315,10 @@ class Day04: AOCDay { } XCTAssertEqual(test: "testAddActivity number of days", withExpression: (repo.activitiesForDay.keys.count == 5)) var count = repo.activitiesForDay[342]?.count ?? 0 - // print("count : \(count)") XCTAssertEqual(test: "testAddActivity activies day 1", withExpression: (count == 5)) count = repo.activitiesForDay[343]?.count ?? 0 - // print("count : \(count)") XCTAssertEqual(test: "testAddActivity activies day 2", withExpression: (count == 3)) count = repo.activitiesForDay[344]?.count ?? 0 - // print("count : \(count)") XCTAssertEqual(test: "testAddActivity activies day 3", withExpression: (count == 3)) } @@ -387,15 +365,18 @@ class Day04: AOCDay { repo.add(histogram: hist, toID: repo.findID(forDay: day)) } var tuple = repo.sumMinutes(forID: 10) - XCTAssertEqual(test: "testSumMinutes id 10", withExpression: (tuple == (50, 24))) + let passTest = (tuple.total == 50) && (tuple.maxMinute == 24) + XCTAssertEqual(test: "testSumMinutes id 10", withExpression: passTest) tuple = repo.sumMinutes(forID: 99) - XCTAssertEqual(test: "testSumMinutes id 99", withExpression: (tuple == (30, 45))) + XCTAssertEqual(test: "testSumMinutes id 99", withExpression: (tuple == (30, 45, 3))) } func testFindGuard() { let repo = Repose(withString: testData) - let answer = repo.findGuard() - XCTAssertEqual(test: "testFindGuard", withExpression: (answer == (10, 24))) + var answer = repo.findGuard(forPart1: true) + XCTAssertEqual(test: "testFindGuard Part 1", withExpression: (answer == (10, 24))) + answer = repo.findGuard(forPart1: false) + XCTAssertEqual(test: "testFindGuard Part 2", withExpression: (answer == (99, 45))) } func day04Tests() { @@ -410,12 +391,10 @@ class Day04: AOCDay { } func day04Final() { - let retVal = "None" let repo = Repose(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day04.txt") - // let repo = Repose(withString: testData) - let answer = repo.findGuard() - print("answer=\(answer)") + var answer = repo.findGuard(forPart1: true) print("Answer to part 1 is: \(answer.id * answer.minute)") - print("Answer to part 2 is: \(retVal)") + answer = repo.findGuard(forPart1: false) + print("Answer to part 2 is: \(answer.id * answer.minute)") } } diff --git a/Sources/AOC2018/main.swift b/Sources/AOC2018/main.swift index 59b4825..5368932 100644 --- a/Sources/AOC2018/main.swift +++ b/Sources/AOC2018/main.swift @@ -5,7 +5,7 @@ import Foundation let showTests = true -let onlyOneDay = 4 +let onlyOneDay = 0 var allTests: [(() -> ())] = [] var allFinal: [(() -> ())] = []