Finish Day 4

master
Peter 7 years ago
parent 6ba10d386f
commit de4e101672

@ -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 // Make some assumptions based on the fact that there is only on guard on duty per night
// read in data // read in data
@ -42,7 +37,7 @@ struct GuardMap {
// - create histogram and determine which minute he has slept through the most // - create histogram and determine which minute he has slept through the most
class Repose { class Repose {
var scheduleArray: [String] = [] 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]] = [:] var activitiesForDay: [Int : [Activity]] = [:]
// Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day04.txt' // 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 // 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 } guard let lastStr = scheduleArray.last, lastStr.count == 0 else { return }
scheduleArray.removeLast() // empty string scheduleArray.removeLast() // empty string
// parseData(withSchedule: scheduleArray)
} }
// Supply test data in the form of a String // Supply test data in the form of a String
init(withString schedule: String) { init(withString schedule: String) {
scheduleArray = schedule.components(separatedBy: "\n") 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 { 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. // 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. // 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 myDay = 31
myMonth -= 1 myMonth -= 1
} }
// print("input Day = \(day), myMonth=\(myMonth), myDay=\(myDay)")
if myDay == nDays[myMonth - 1] { if myDay == nDays[myMonth - 1] {
retVal = (myMonth + 1) * 31 + 1 retVal = (myMonth + 1) * 31 + 1
} else { } else {
retVal = day + 1 retVal = day + 1
} }
// print("newDay = \(retVal)")
return retVal return retVal
} }
@ -91,7 +83,6 @@ class Repose {
if line.count > 0 { if line.count > 0 {
// Split line into time and action // Split line into time and action
var parseString = line var parseString = line
// print("\n\(line)")
parseString.removeFirst() parseString.removeFirst()
let splitStr = parseString.components(separatedBy: "]") let splitStr = parseString.components(separatedBy: "]")
guard splitStr.count > 1 else { break parseScope } guard splitStr.count > 1 else { break parseScope }
@ -127,14 +118,12 @@ class Repose {
startShiftStr.removeFirst() startShiftStr.removeFirst()
retVal.id = Int(startShiftStr.components(separatedBy: " ")[0]) ?? -1 retVal.id = Int(startShiftStr.components(separatedBy: " ")[0]) ?? -1
} }
// print("source line : \(retVal.day) \(hour) : \(retVal.minute) -- splitStr '\(actionStr)'\n")
} }
return retVal return retVal
} }
func add(activity: Activity) { func add(activity: Activity) {
if activitiesForDay[activity.day] == nil { if activitiesForDay[activity.day] == nil {
// print("adding day \(activity.day) activity : \(activity)")
activitiesForDay[activity.day] = [activity] activitiesForDay[activity.day] = [activity]
} else { } else {
activitiesForDay[activity.day]!.append(activity) activitiesForDay[activity.day]!.append(activity)
@ -149,7 +138,6 @@ class Repose {
for day in activitiesForDay.keys { for day in activitiesForDay.keys {
activitiesForDay[day]!.sort() activitiesForDay[day]!.sort()
sleepMapForGuardID[findID(forDay: day)] = Array(repeating: 0, count: 60) 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] { func buildHistogram(forDay day: Int) -> [Int] {
var retVal = Array(repeating: 0, count: 60) 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() addActivitiesIfNecessary()
if let array = activitiesForDay[day] { if let array = activitiesForDay[day] {
var startSleep = 0 var startSleep = 0
@ -180,7 +166,6 @@ class Repose {
retVal[min] = 1 retVal[min] = 1
} }
} }
// print("\(activity)")
} }
} }
return retVal return retVal
@ -197,19 +182,19 @@ class Repose {
} }
// Sum all the minutes slept, retrun the total and the minute of most sleeps // Sum all the minutes slept, retrun the total and the minute of most sleeps
func sumMinutes(forID id: Int) -> (total: Int, maxMinute: Int) { func sumMinutes(forID id: Int) -> (total: Int, maxMinute: Int, maxMinuteVal: Int) {
var retVal = (total: 0, maxMinute: -1) var retVal = (total: 0, maxMinute: -1, maxMinuteVal: -1)
guard var array = sleepMapForGuardID[id] else { return retVal } guard var array = sleepMapForGuardID[id] else { return retVal }
guard array.count == 60 else { return retVal } guard array.count == 60 else { return retVal }
for i in 0..<60 { for i in 0..<60 {
retVal.total += array[i] retVal.total += array[i]
} }
retVal.maxMinute = array.firstIndex(of: (array.max() ?? 1)) ?? 0 retVal.maxMinuteVal = array.max() ?? 1
// print("ID:\(id), retVal:\(retVal)") retVal.maxMinute = array.firstIndex(of: retVal.maxMinuteVal) ?? 0
return retVal return retVal
} }
func findGuard() -> (id: Int, minute: Int) { func findGuard(forPart1 part1: Bool) -> (id: Int, minute: Int) {
var retVal = (id: 0, minute: -1) var retVal = (id: 0, minute: -1)
addActivitiesIfNecessary() addActivitiesIfNecessary()
for day in activitiesForDay.keys { for day in activitiesForDay.keys {
@ -219,18 +204,16 @@ class Repose {
var maxTime = 0 var maxTime = 0
for id in sleepMapForGuardID.keys { for id in sleepMapForGuardID.keys {
let stats = sumMinutes(forID: id) let stats = sumMinutes(forID: id)
if stats.total > maxTime { let maxForPart = part1 ? stats.total : stats.maxMinuteVal
maxTime = stats.total if maxForPart > maxTime {
maxTime = maxForPart
retVal.minute = stats.maxMinute retVal.minute = stats.maxMinute
retVal.id = id retVal.id = id
} }
} }
return retVal 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 // Need a state-machine
// - start shift // - start shift
@ -246,7 +229,6 @@ class Repose {
// 11-04 #99 ....................................##########.............. // 11-04 #99 ....................................##########..............
// 11-05 #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 // #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 { class Day04: AOCDay {
lazy var tests: (() -> ()) = day04Tests lazy var tests: (() -> ()) = day04Tests
@ -306,7 +288,6 @@ class Day04: AOCDay {
func testPasrseLine() { func testPasrseLine() {
var response = Repose.parse(line: "") var response = Repose.parse(line: "")
// print("Response : \(response)")
XCTAssertEqual(test: "testPasrseLine empty", withExpression: (response.minute == -1)) XCTAssertEqual(test: "testPasrseLine empty", withExpression: (response.minute == -1))
let repo = Repose(withString: testData) let repo = Repose(withString: testData)
response = Repose.parse(line: repo.scheduleArray[0]) 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)) XCTAssertEqual(test: "testAddActivity number of days", withExpression: (repo.activitiesForDay.keys.count == 5))
var count = repo.activitiesForDay[342]?.count ?? 0 var count = repo.activitiesForDay[342]?.count ?? 0
// print("count : \(count)")
XCTAssertEqual(test: "testAddActivity activies day 1", withExpression: (count == 5)) XCTAssertEqual(test: "testAddActivity activies day 1", withExpression: (count == 5))
count = repo.activitiesForDay[343]?.count ?? 0 count = repo.activitiesForDay[343]?.count ?? 0
// print("count : \(count)")
XCTAssertEqual(test: "testAddActivity activies day 2", withExpression: (count == 3)) XCTAssertEqual(test: "testAddActivity activies day 2", withExpression: (count == 3))
count = repo.activitiesForDay[344]?.count ?? 0 count = repo.activitiesForDay[344]?.count ?? 0
// print("count : \(count)")
XCTAssertEqual(test: "testAddActivity activies day 3", withExpression: (count == 3)) 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)) repo.add(histogram: hist, toID: repo.findID(forDay: day))
} }
var tuple = repo.sumMinutes(forID: 10) 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) 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() { func testFindGuard() {
let repo = Repose(withString: testData) let repo = Repose(withString: testData)
let answer = repo.findGuard() var answer = repo.findGuard(forPart1: true)
XCTAssertEqual(test: "testFindGuard", withExpression: (answer == (10, 24))) 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() { func day04Tests() {
@ -410,12 +391,10 @@ class Day04: AOCDay {
} }
func day04Final() { func day04Final() {
let retVal = "None"
let repo = Repose(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day04.txt") let repo = Repose(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day04.txt")
// let repo = Repose(withString: testData) var answer = repo.findGuard(forPart1: true)
let answer = repo.findGuard()
print("answer=\(answer)")
print("Answer to part 1 is: \(answer.id * answer.minute)") 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 import Foundation
let showTests = true let showTests = true
let onlyOneDay = 4 let onlyOneDay = 0
var allTests: [(() -> ())] = [] var allTests: [(() -> ())] = []
var allFinal: [(() -> ())] = [] var allFinal: [(() -> ())] = []

Loading…
Cancel
Save