Build a report from study sessions
Create a pure pipeline that validates sessions, groups them by topic, and returns total minutes sorted by descending total and then title. Reject negative durations instead of silently discarding them.
data class Study(val topic: String, val minutes: Int)
fun totals(studies: List<Study>): List<Pair<String, Int>> {
require(studies.all { it.minutes >= 0 && it.topic.isNotBlank() })
return studies.groupBy { it.topic.trim() }
.map { (topic, entries) -> topic to entries.sumOf { it.minutes } }
.sortedWith(compareByDescending<Pair<String, Int>> { it.second }.thenBy { it.first })
}
The explicit tie-breaker makes results deterministic. sumOf over Int values can overflow, so choose Long for totals when your input bounds require it.
Acceptance checks
Test empty input, repeated topics, whitespace normalization, equal totals, zero minutes, and invalid negative minutes. Expected output for Kotlin/25, Compose/10, Kotlin/15 is Kotlin/40 followed by Compose/10.
Extension: return a named data class rather than Pair, and add a report of rejected input when partial ingestion is a requirement. Explain why silently dropping invalid records can misrepresent totals.