Files
advent-of-code/internal/2018/DayFour/code.go

89 lines
1.9 KiB
Go

package dayfour
import (
"os"
"regexp"
"slices"
"strconv"
"strings"
"time"
"advent-of-code/internal/registry"
)
var guardRegex = regexp.MustCompile(`Guard #(\d+) begins shift`)
func init() {
registry.Register("2018D4", ParseInput, PartOne, PartTwo)
}
func ParseInput(filepath string) []string {
content, _ := os.ReadFile(filepath)
return strings.Split(string(content), "\n")
}
type record struct {
timestamp time.Time
action string
guardID int
}
func PartOne(data []string) int {
records := make([]record, 0, len(data))
timeLayout := "2006-01-02 15:04"
for _, line := range data {
timeStr, action, _ := strings.Cut(line[1:], "] ")
timestamp, _ := time.Parse(timeLayout, timeStr)
guardID := -1
if matches := guardRegex.FindStringSubmatch(action); matches != nil {
guardID, _ = strconv.Atoi(matches[1])
}
records = append(records, record{timestamp, action, guardID})
}
slices.SortFunc(records, func(a, b record) int {
return a.timestamp.Compare(b.timestamp)
})
guardSleepMinutes := make(map[int]int)
guardMinuteCount := make(map[int]map[int]int)
currentGuard := -1
for i := range records {
if records[i].guardID != -1 {
currentGuard = records[i].guardID
if guardMinuteCount[currentGuard] == nil {
guardMinuteCount[currentGuard] = make(map[int]int)
}
}
if records[i].action == "falls asleep" && i+1 < len(records) {
start, end := records[i].timestamp.Minute(), records[i+1].timestamp.Minute()
guardSleepMinutes[currentGuard] += end - start
for m := start; m < end; m++ {
guardMinuteCount[currentGuard][m]++
}
}
}
maxGuard, maxMinutes := -1, 0
for id, minutes := range guardSleepMinutes {
if minutes > maxMinutes {
maxGuard, maxMinutes = id, minutes
}
}
maxMinute, maxCount := -1, 0
for m, count := range guardMinuteCount[maxGuard] {
if count > maxCount {
maxMinute, maxCount = m, count
}
}
return maxGuard * maxMinute
}
func PartTwo(data []string) int {
return 0
}