Finish Day 4
This commit is contained in:
+22
-43
@@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import Foundation
|
||||
|
||||
let showTests = true
|
||||
let onlyOneDay = 4
|
||||
let onlyOneDay = 0
|
||||
var allTests: [(() -> ())] = []
|
||||
var allFinal: [(() -> ())] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user