Day4
This commit is contained in:
117
src/main/kotlin/com/basdado/adventofcode/Day4.kt
Normal file
117
src/main/kotlin/com/basdado/adventofcode/Day4.kt
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.basdado.adventofcode
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.util.stream.Collectors
|
||||
import java.util.stream.IntStream
|
||||
|
||||
fun main() {
|
||||
|
||||
val day = Day4()
|
||||
day.puzzle1()
|
||||
day.puzzle2()
|
||||
}
|
||||
|
||||
class Day4 {
|
||||
|
||||
fun puzzle1() {
|
||||
|
||||
val guardDays = parseDayInput()
|
||||
val maxSleepGuard = guardDays.stream()
|
||||
.collect(Collectors.groupingBy({ g: GuardDay -> g.guardId },
|
||||
Collectors.mapping({ g -> g.totalSleep() },
|
||||
Collectors.summingInt { s: Int -> s }
|
||||
)))
|
||||
.maxBy { it.value }!!
|
||||
|
||||
val guardSleeps = guardDays.stream()
|
||||
.filter{ it.guardId == maxSleepGuard.key}
|
||||
.flatMap { it.sleeps.stream() }
|
||||
.collect(Collectors.toList())
|
||||
|
||||
val sleepMinutes = IntArray(60)
|
||||
guardSleeps.forEach { IntStream.range(it.start, it.end).forEach{ m -> sleepMinutes[m]++ } }
|
||||
|
||||
val maxSleepMinute = sleepMinutes.indexOf(sleepMinutes.max()!!)
|
||||
println(maxSleepMinute * maxSleepGuard.key)
|
||||
}
|
||||
|
||||
fun puzzle2() {
|
||||
|
||||
val guardDays = parseDayInput()
|
||||
|
||||
val guardsSleepMinutes = guardDays.stream().map { it.guardId }
|
||||
.distinct()
|
||||
.collect(Collectors.toMap( { id: Int -> id }, {IntArray(60)}))
|
||||
|
||||
guardDays.stream()
|
||||
.forEach {
|
||||
val guardSleepMinutes = guardsSleepMinutes[it.guardId]!!
|
||||
it.sleeps.forEach { s ->
|
||||
IntStream.range(s.start, s.end).forEach{ m -> guardSleepMinutes[m]++ }
|
||||
}
|
||||
}
|
||||
|
||||
val maxSleepMinuteGuard = guardsSleepMinutes.maxBy { it.value.max()!! }!!
|
||||
|
||||
val maxSleepMinute = maxSleepMinuteGuard.value.indexOf(maxSleepMinuteGuard.value.max()!!)
|
||||
println(maxSleepMinute * maxSleepMinuteGuard.key)
|
||||
|
||||
}
|
||||
|
||||
fun parseDayInput(): List<GuardDay> {
|
||||
val sortedLines = lines("/day/4/input.txt")
|
||||
.map { parseLine(it) }
|
||||
.filter{ it != null }
|
||||
.map { it!! }
|
||||
.sorted( Comparator.comparing { l: Line -> l.date}.thenComparing { l -> l.hour }.thenComparing { l -> l.minute})
|
||||
.collect(Collectors.toList())
|
||||
|
||||
return parseGuardDays(sortedLines)
|
||||
}
|
||||
|
||||
private fun parseGuardDays(sortedLines: MutableList<Line>): List<GuardDay> {
|
||||
val guardDays = mutableListOf<GuardDay>()
|
||||
var currentDay = GuardDay(0, LocalDate.EPOCH, mutableListOf())
|
||||
var sleepStartMinute = 0
|
||||
for (line in sortedLines) {
|
||||
if (line.event == GuardEventType.BEGIN_SHIFT) {
|
||||
if (currentDay.guardId != 0) guardDays.add(currentDay)
|
||||
currentDay = GuardDay(line.guardId!!, line.date, mutableListOf())
|
||||
} else if (line.event == GuardEventType.FALL_ASLEEP) {
|
||||
sleepStartMinute = line.minute
|
||||
} else if (line.event == GuardEventType.WAKE_UP) {
|
||||
currentDay.sleeps.add(GuardSleep(sleepStartMinute, line.minute))
|
||||
}
|
||||
}
|
||||
return guardDays
|
||||
}
|
||||
|
||||
fun parseLine(line: String): Line? {
|
||||
val regex = Regex("""\[(\d+)-(\d+)-(\d+) (\d+):(\d+)] (Guard #(\d+) begins shift|falls asleep|wakes up)""")
|
||||
val match = regex.matchEntire(line) ?: return null
|
||||
return Line(
|
||||
LocalDate.of(match.groups[1]!!.value.toInt(), match.groups[2]!!.value.toInt(), match.groups[3]!!.value.toInt()),
|
||||
match.groups[4]!!.value.toInt(),
|
||||
match.groups[5]!!.value.toInt(),
|
||||
parseEventType(match.groups[6]!!.value),
|
||||
match.groups[7]?.value?.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
fun parseEventType(eventString: String): GuardEventType {
|
||||
return when(eventString) {
|
||||
"falls asleep" -> GuardEventType.FALL_ASLEEP
|
||||
"wakes up" -> GuardEventType.WAKE_UP
|
||||
else -> GuardEventType.BEGIN_SHIFT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Line(val date: LocalDate, val hour: Int, val minute: Int, val event: GuardEventType, val guardId: Int?)
|
||||
enum class GuardEventType { BEGIN_SHIFT, FALL_ASLEEP, WAKE_UP }
|
||||
data class GuardDay (val guardId: Int, val date: LocalDate, val sleeps: MutableList<GuardSleep>) {
|
||||
fun totalSleep(): Int = sleeps.stream().mapToInt{ it.sleep() }.sum()
|
||||
}
|
||||
data class GuardSleep (val start: Int, val end: Int) {
|
||||
fun sleep(): Int = end - start
|
||||
}
|
||||
@@ -8,4 +8,4 @@ fun lines(resourceFile: String): Stream<String> {
|
||||
return Files.lines(Paths.get(Utils::class.java.getResource(resourceFile).toURI()))
|
||||
}
|
||||
|
||||
class Utils;
|
||||
class Utils
|
||||
1110
src/main/resources/day/4/input.txt
Normal file
1110
src/main/resources/day/4/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user