Programmers/Lv. 2

[Kotlin] Programmers Lv. 2 주차 요금 계산

chattymin 2023. 3. 20. 22:49
728x90
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/92341

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제


Code

fun solution(fees: IntArray, records: Array<String>): IntArray {
    var answer: MutableMap<String, Int> = mutableMapOf()

    // fees : 기본시간, 기본요금, 단위시간, 단위요금
    // => defaultFee + (총 소요시간 - defaultTime)올림 * unitFee
    val defaultTime = fees[0]
    val defaultFee = fees[1]
    val unitTime = fees[2]
    val unitFee = fees[3]

    var carRecord: Array<Car> = arrayOf()
    var calcRecord: Array<Calc> = arrayOf()

    for (i in records){
        val temp = i.split(" ")
        carRecord = carRecord.plus(
            Car(
                temp[0].slice(0..1).toInt(), // hour
                temp[0].slice(3..4).toInt(), // minute
                temp[1],
                temp[2]
            ))
    }

    // 시간 계산
    for (i in 0 until carRecord.size){
        if (carRecord[i].state == "IN"){
            val temp = carRecord.slice(i until carRecord.size).find { it.state == "OUT" && it.carNum == carRecord[i].carNum }
            val time = (((temp?.hour?:23) - (carRecord[i].hour)) * 60) + ((temp?.minute?:59) - (carRecord[i].minute))
            calcRecord = calcRecord.plus(Calc(carRecord[i].carNum, time))
        }
    }

    //차량번호로 정렬
    calcRecord.sortBy { it.carNum }

    // 요금 계산
    for (i in calcRecord){
        // 중복확인
        if (answer.keys.contains(i.carNum)) continue

        // 시간 합산
        val temp = calcRecord.filter { it.carNum == i.carNum }.sumOf { it.time }

        var usingTime = (temp - defaultTime) / unitTime.toDouble()

        // 기본시간보다 적게 사용했을경우 기본요금 부과
        if (usingTime <= 0){
            answer.put(i.carNum, defaultFee)
            continue
        }

        // 반올림 -> 내장함수 사용하는 방법으로 변형해보자.
        if (usingTime%1 >0) usingTime = usingTime/10 * 10 + 1

        var result = defaultFee + usingTime.toInt() * unitFee

        answer.put(i.carNum, result)
    }

    return answer.values.toIntArray()
}

class Car(val hour: Int, val minute: Int, val carNum: String, val state: String)

class Calc(val carNum: String, val time: Int)

풀이

우선 차량의 출차 기록을 class로 만들어서 관리하고자 했다. 

입력값을 split을 활용하여 입/출차시간, 차량번호, 입/출차여부를 나누어 저장했다.

입/출차시간의 경우 slice 기능을 활용하여 시간과 분을 나눠 int로 저장했다.

for (i in records){
    val temp = i.split(" ")
    carRecord = carRecord.plus(
        Car(
            temp[0].slice(0..1).toInt(), // hour
            temp[0].slice(3..4).toInt(), // minute
            temp[1],
            temp[2]
        ))
}

 

저장한 출차기록을 바탕으로 시간을 계산하여 Calc 클래스에 맞춰 저장한다.

입/출차여부가 IN일 경우 아래와 같은 식을 실행한다. 

해당 번호와 같은 차량의 OUT 기록을 찾고 시간과 분을 계산해서 time에 저장한다. 만약 존재하지 않을경우 엘비스연산자를 활용하여 23:59분으로 계산한다.

if (carRecord[i].state == "IN"){
    val temp = carRecord.slice(i until carRecord.size).find { it.state == "OUT" && it.carNum == carRecord[i].carNum }
    val time = (((temp?.hour?:23) - (carRecord[i].hour)) * 60) + ((temp?.minute?:59) - (carRecord[i].minute))
    calcRecord = calcRecord.plus(Calc(carRecord[i].carNum, time))
}

 

문제의 기준에 맞추어 차량번호로 정렬을 해주고, 요금 계산을 진행한다.

answer의 map을 활용하여 차량번호와 요금을 저장한다.

위에서 계산한 배열을 순회하며 시간을 활용하여 요금을 계산하고, 해당 요금과 차량 번호를 저장한다.

만약, 배열에 해당 차량번호가 존재한다면 모든 과정을 생략하고 다음 값을 계산한다.

만약, 사용시간이 기본시간보다 작다면 기본요금만 부과하고 넘어간다. 그게 아니라면 올림을 사용하여 값을 계산해준다.

// 요금 계산
for (i in calcRecord){
    // 중복확인
    if (answer.keys.contains(i.carNum)) continue

    // 시간 합산
    val temp = calcRecord.filter { it.carNum == i.carNum }.sumOf { it.time }

    var usingTime = (temp - defaultTime) / unitTime.toDouble()

    // 기본시간보다 적게 사용했을경우 기본요금 부과
    if (usingTime <= 0){
       answer.put(i.carNum, defaultFee)
       continue
    }

    // 반올림 -> 내장함수 사용하는 방법으로 변형해보자.
    if (usingTime%1 >0) usingTime = usingTime/10 * 10 + 1

    var result = defaultFee + usingTime.toInt() * unitFee

    answer.put(i.carNum, result)
}

마지막에는 해당 결과를 담고있는 value를 IntArray로 형변환하여 리턴하면 끝.

 

 

Lv. 2에다가 카카오에서 사용한 문제라고 해서 많이 쫄았었는데 생각보다는 쉬웠다. 하지만, 세부적인부분에서 약간씩 아쉬운 부분이 보인다. val로 해도 되는걸 var로 했다거나, 불필요한 변수사용이 좀 있었던거 같다. 일부 수정해서 블로그에 업로드 하긴 하지만, 로직이라거나 메모리관리 측면이 많이 부족해보인다.

728x90
반응형