This commit is contained in:
2018-12-04 15:25:28 +01:00
parent e1db08580a
commit 60233e8159
3 changed files with 1228 additions and 1 deletions

View 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
}

View File

@@ -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

File diff suppressed because it is too large Load Diff