package assignment.week3.taxipark /* * Task #1. Find all the drivers who performed no trips. */ fun TaxiPark.findFakeDrivers(): Set = this.allDrivers .filter { driver -> this.trips.none { trip -> trip.driver == driver } } .toSet() /* * Task #2. Find all the clients who completed at least the given number of trips. */ fun TaxiPark.findFaithfulPassengers(minTrips: Int): Set = this.allPassengers .filter { passenger -> this.trips.count { trip -> trip.passengers.contains(passenger) } >= minTrips } .toSet() /* * Task #3. Find all the passengers, who were taken by a given driver more than once. */ fun TaxiPark.findFrequentPassengers(driver: Driver): Set = this.allPassengers .filter { passenger -> this.trips .filter { trip -> trip.passengers.contains(passenger) } .count { trip -> trip.driver == driver } > 1 } .toSet() /* * Task #4. Find the passengers who had a discount for majority of their trips. */ fun TaxiPark.findSmartPassengers(): Set = this.allPassengers .filter(fun(passenger: Passenger): Boolean { val (discounted, nonDiscounted) = this.trips .filter { it.passengers.contains(passenger) } .partition { it.discount != null } if (nonDiscounted.isEmpty()) { return discounted.isNotEmpty() } return (discounted.size.toDouble()) / nonDiscounted.size > 1.0 }) .toSet() /* * Task #5. Find the most frequent trip duration among minute periods 0..9, 10..19, 20..29, and so on. * Return any period if many are the most frequent, return `null` if there're no trips. */ fun TaxiPark.findTheMostFrequentTripDurationPeriod(): IntRange? { val (maxDuration, _) = this.trips .map { trip -> trip.duration / 10 } .groupBy { it } .maxByOrNull { it.value.size } ?: return null val startRange = maxDuration * 10 return startRange.rangeTo(startRange + 9) } /* * Task #6. * Check whether 20% of the drivers contribute 80% of the income. */ fun TaxiPark.checkParetoPrinciple(): Boolean { if (this.trips.isEmpty()) { return false } val totalIncome = this.trips.sumOf(Trip::cost) val top20Percent = this.trips .groupBy { it.driver } .values .map { trips -> trips.sumOf(Trip::cost) } .sortedDescending() .take((this.allDrivers.size * 0.2).toInt()) .sum() return top20Percent >= totalIncome * 0.8 }