Android/Kotlin

[cousera] Kotlin Week3 Taxi Driver

MOVE🔥 2019. 11. 11. 20:05
728x90
반응형

 

1. 한번도 운전 못한 택시기사 찾기 

-> filterNot 함수를 이용하여 Trip한 driver 들을 제외시켰다.

/*
 * Task #1. Find all the drivers who performed no trips.
 */
fun TaxiPark.findFakeDrivers(): Set<Driver> =
        this.allDrivers.filterNot { this.trips.map{trip -> trip.driver }.contains(it) }.toSet()

 

2. minTrips번 만큼 Trip한 승객 찾기

-> Trip에서 승객 count하여 minTrips수보다 큰경우를 구한다.

/*
 * Task #2. Find all the clients who completed at least the given number of trips.
 */
fun TaxiPark.findFaithfulPassengers(minTrips: Int): Set<Passenger> =
        this.allPassengers.filter { passenger -> this.trips.flatMap { trip -> trip.passengers }.count{it == passenger} >= minTrips }.toSet()

 

3. driver의 택시를 한번이상 탄 승객

-> 2번과 비슷하게 풀었다. (근데 너무 길다)

/*
 * Task #3. Find all the passengers, who were taken by a given driver more than once.
 */
fun TaxiPark.findFrequentPassengers(driver: Driver): Set<Passenger> =
        this.allPassengers.filter { passenger -> this.trips.filter{ trip -> trip.driver == driver }.flatMap{ trip -> trip.passengers}.count { it == passenger } > 1}.toSet()

 

4. 반 이상 할인받고 다니는 승객 구하기

-> (겁나길어...)

/*
 * Task #4. Find the passengers who had a discount for majority of their trips.
 */
fun TaxiPark.findSmartPassengers(): Set<Passenger> =
         this.allPassengers.filter { ( this.trips.filter{ trip -> trip.passengers.contains(it) }.count{ ftrip -> ftrip.discount != null && ftrip.discount!! > 0.0 }  > this.trips.filter{ trip -> trip.passengers.contains(it) }.count()/2) }.toSet()

 

5. 가장 많이 간 거리 range 구하기

-> Partition 함수를 이용했다.

5-1. 루프문을 돌면서 검사할 부분과 나머지 부분, 2가지로 나눈다.
5-2. 검사할 부분의 개수와 검사 range를 저장한다. 
5-3. 나머지 부분에 항목이 남아있으면 나머지 부분을 전체부분으로 치환한다.
5-4. 나머지 부분에 아무것도 존재하지 않을때까지 루프문을 반복한다.
/*
 * 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? {
    var cur_range = 10
    var durations = this.trips.map { trip -> trip.duration }
    var duration_rages : MutableMap<IntRange?,Int> = mutableMapOf(null to 0)
    while(true){
        var (parted, unparted) = durations?.partition { it < cur_range }
        duration_rages.put(cur_range-10..cur_range-1 , parted.count())
        if (durations.count() == 0){break}
        cur_range += 10
        durations = unparted
    }
    return duration_rages?.maxBy { it.value }?.key
}

 

6. 상위 20%의 driver가 Taxi 산업의 총수입의 80%를 차지하는가?

6-1. taxi driver의 상위 20% 숫자를 구한다.
6-2. taxi driver와 그의 수입을 group by함수와 sum함수로 계산하여 묶는다.
6-3. taxi driver의 수입을 기준으로 정렬하여 상위 20%와 80% 총수입을 비교한다.
/*
 * Task #6.
 * Check whether 20% of the drivers contribute 80% of the income.
 */
fun TaxiPark.checkParetoPrinciple(): Boolean {
    //총 수입
    val total_income = this.trips.map { trip -> trip.cost }.sum()
    // taxi driver 20% 상위 숫자
    val topDriver_num : Int = this.allDrivers.count() / 5
    // driver, driver의 총 수입 배열
    var drivers_income = this.trips.map{it.driver to it.cost}.groupBy{it.first}.mapValues { it.value.sumByDouble { it.second } }
    //상위 20% 드라이버의 수입과 총수입의 80% 비교
    if ( total_income == 0.0 || drivers_income.values.sortedDescending().take(topDriver_num).sum() < total_income * 0.8) {
        return false
    }
    return true

}

 

 

배열안에 구조체 배열.. 같은 복잡한 구조여서 진행하는데 조금 햇갈렸던것 같다.

쓸데없이 코드들이 길어지고 해석하는데도 좀 걸리는 것이 좋은 코드는 아닌것 같은데..

정답코드보고 현타나 맞고와야지

 

 

728x90
반응형