adventofcode/2018/day04/day04.go

153 lines
3.0 KiB
Go
Raw Permalink Normal View History

2018-12-04 15:33:40 +00:00
package main
import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strconv"
"strings"
"time"
)
var guards map[int]*Guard
func main() {
inp := StdinToStringSlice()
buildGuardMap(inp)
part1()
part2()
}
func buildGuardMap(inp []string) {
sort.Strings(inp)
guards = make(map[int]*Guard)
var currGuard int
var sleepStart time.Time
for _, v := range inp {
t, _ := time.Parse("2006-01-02 15:04", v[1:17])
actionParts := strings.Split(v[19:], " ")
switch actionParts[0][0] {
case 'G':
currGuard = Atoi(actionParts[1][1:])
case 'f':
sleepStart = t
case 'w':
if _, ok := guards[currGuard]; !ok {
guards[currGuard] = &Guard{
id: currGuard,
totalSleepTime: 0,
sleepLog: make([]Nap, 0, 5),
}
}
guards[currGuard].TakeNap(sleepStart, t)
}
}
}
func part1() {
var sleepiest int
var sleepiestTime int
for k, v := range guards {
if v.TotalNapTime() > sleepiestTime {
sleepiest = k
sleepiestTime = v.TotalNapTime()
}
}
min, _ := guards[sleepiest].GetSleepiestMinute()
fmt.Println("= Part 1 =")
fmt.Println("Sleepiest Guard:", sleepiest, "(", sleepiestTime, ") Sleepiest Minute:", min)
fmt.Println("= Answer =")
fmt.Println(sleepiest * min)
}
func part2() {
var sleepiestTime int
type tuple struct {
v1, v2 int
}
sleepiestMinutes := make(map[int]tuple)
for _, v := range guards {
v1, v2 := v.GetSleepiestMinute()
sleepiestMinutes[v.id] = tuple{v1, v2}
if v.TotalNapTime() > sleepiestTime {
sleepiestTime = v.TotalNapTime()
}
}
var highestCount, highestCountGuard, highestCountMinute int
for k, v := range sleepiestMinutes {
if v.v2 > highestCount {
highestCount = v.v2
highestCountGuard = k
highestCountMinute = v.v1
}
}
fmt.Println("= Part 2 =")
fmt.Printf("Guard: %d\nMinute: %d\nCount: %d\n", highestCountGuard, highestCountMinute, highestCount)
fmt.Println("= Answer =")
fmt.Println(highestCountGuard * highestCountMinute)
}
type Guard struct {
id int
totalSleepTime int
sleepLog []Nap
}
func (g *Guard) TakeNap(start, end time.Time) {
g.sleepLog = append(
g.sleepLog,
Nap{start: start, end: end})
}
func (g *Guard) TotalNapTime() int {
var ret int
for _, v := range g.sleepLog {
ret += int(v.end.Sub(v.start).Minutes())
}
return ret
}
func (g *Guard) GetSleepiestMinute() (int, int) {
minuteMap := make(map[int]int)
for _, v := range g.sleepLog {
wrkMin := v.start.Minute()
for wrkMin < v.end.Minute() {
minuteMap[wrkMin]++
wrkMin++
}
}
var sleepiestMinute, sleepiestCount int
for k, v := range minuteMap {
if v > sleepiestCount {
sleepiestMinute = k
sleepiestCount = v
}
}
return sleepiestMinute, minuteMap[sleepiestMinute]
}
type Nap struct {
start time.Time
end time.Time
}
func StdinToStringSlice() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}