Refactor assignment 3 and implement alternative Pareto Principle

This commit is contained in:
Martin Berg Alstad
2025-08-01 09:24:57 +02:00
committed by Martin Berg Alstad
parent 6ef68a5e05
commit 0ae450d294
4 changed files with 97 additions and 32 deletions

View File

@ -1,25 +1,22 @@
package nicestring package assignment.week3.nicestring
fun String.isNice(): Boolean { const val VOWELS = "aeiou"
return listOf(
::containsNotNiceSubstring,
::containsAtLeastThreeVowels,
::containsDoubleLetter
)
.count { it() } >= 2
}
fun String.containsNotNiceSubstring(): Boolean { fun String.isNice(): Boolean = listOf(
::containsNotNiceSubstring,
::containsAtLeastThreeVowels,
::containsDoubleLetter
).count { it() } >= 2
private fun String.containsNotNiceSubstring(): Boolean {
val illegalSubStrings = listOf("bu", "ba", "be") val illegalSubStrings = listOf("bu", "ba", "be")
return this.zipWithNext() return this.zipWithNext()
.map { (first, second) -> "$first$second" } .map { (first, second) -> "$first$second" }
.none { it in illegalSubStrings } .none { it in illegalSubStrings }
} }
fun String.containsAtLeastThreeVowels(): Boolean { private fun String.containsAtLeastThreeVowels(): Boolean =
val vovels = "aeiou".toCharArray() this.count { char -> char in VOWELS.toCharArray() } >= 3
return this.count { char -> char in vovels } >= 3
}
fun String.containsDoubleLetter(): Boolean = this.zipWithNext() private fun String.containsDoubleLetter(): Boolean = this.zipWithNext()
.any { (first, second) -> first == second } .any { (first, second) -> first == second }

View File

@ -1,22 +1,23 @@
package taxipark package assignment.week3.taxipark
data class TaxiPark( data class TaxiPark(
val allDrivers: Set<Driver>, val allDrivers: Set<Driver>,
val allPassengers: Set<Passenger>, val allPassengers: Set<Passenger>,
val trips: List<Trip>) val trips: List<Trip>
)
data class Driver(val name: String) data class Driver(val name: String)
data class Passenger(val name: String) data class Passenger(val name: String)
data class Trip( data class Trip(
val driver: Driver, val driver: Driver,
val passengers: Set<Passenger>, val passengers: Set<Passenger>,
// the trip duration in minutes // the trip duration in minutes
val duration: Int, val duration: Int,
// the trip distance in km // the trip distance in km
val distance: Double, val distance: Double,
// the percentage of discount (in 0.0..1.0 if not null) // the percentage of discount (in 0.0..1.0 if not null)
val discount: Double? = null val discount: Double? = null
) { ) {
// the total cost of the trip // the total cost of the trip
val cost: Double val cost: Double

View File

@ -0,0 +1,67 @@
package assignment.week3.taxipark
fun TaxiPark.checkParetoPrinciple2(): Boolean {
if (trips.isEmpty()) return false
val totalIncome = trips.sumOf { trip -> trip.cost }
val sortedDriversIncome: List<Double> = trips
.groupBy { it.driver }
.map { (_, tripsByDriver) -> tripsByDriver.sumOf { trip -> trip.cost } }
.sortedDescending()
val numberOfTopDrivers = (0.2 * allDrivers.size).toInt()
val incomeByTopDrivers = sortedDriversIncome
.take(numberOfTopDrivers)
.sum()
return incomeByTopDrivers >= 0.8 * totalIncome
}
fun main() {
taxiPark(
1..5, 1..4,
trip(1, 1, 20, 20.0),
trip(1, 2, 20, 20.0),
trip(1, 3, 20, 20.0),
trip(1, 4, 20, 20.0),
trip(2, 1, 20, 19.0)
)
.checkParetoPrinciple() eq true
taxiPark(
1..5, 1..4,
trip(1, 1, 20, 20.0),
trip(1, 2, 20, 20.0),
trip(1, 3, 20, 20.0),
trip(1, 4, 20, 20.0),
trip(2, 1, 20, 21.0)
)
.checkParetoPrinciple2() eq false
}
private infix fun <T> T.eq(other: T) {
if (this != other) throw AssertionError("Expected $this to equal $other")
println("OK")
}
private fun taxiPark(
allDrivers: IntProgression,
allPassengers: IntProgression,
vararg trips: Trip
) = TaxiPark(
allDrivers = allDrivers.map { Driver(it.toString()) }.toSet(),
allPassengers = allPassengers.map { Passenger(it.toString()) }.toSet(),
trips = trips.toList()
)
private fun trip(
driver: Int,
passenger: Int,
duration: Int,
distance: Double
) = Trip(
driver = Driver(driver.toString()),
passengers = setOf(Passenger(passenger.toString())),
duration = duration,
distance = distance
)

View File

@ -1,4 +1,4 @@
package taxipark package assignment.week3.taxipark
/* /*
* Task #1. Find all the drivers who performed no trips. * Task #1. Find all the drivers who performed no trips.
@ -49,13 +49,13 @@ fun TaxiPark.findSmartPassengers(): Set<Passenger> = this.allPassengers
* Return any period if many are the most frequent, return `null` if there're no trips. * Return any period if many are the most frequent, return `null` if there're no trips.
*/ */
fun TaxiPark.findTheMostFrequentTripDurationPeriod(): IntRange? { fun TaxiPark.findTheMostFrequentTripDurationPeriod(): IntRange? {
val maxDuration = this.trips val (maxDuration, _) = this.trips
.map { trip -> trip.duration / 10 } .map { trip -> trip.duration / 10 }
.groupBy { it } .groupBy { it }
.maxByOrNull { it.value.size } .maxByOrNull { it.value.size } ?: return null
val startRange = maxDuration?.let { it.key * 10 } val startRange = maxDuration * 10
return startRange?.let { it.rangeTo(it + 9) } return startRange.rangeTo(startRange + 9)
} }
/* /*