Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16-jung0115 #173

Merged
merged 18 commits into from
Nov 21, 2024
Merged

16-jung0115 #173

merged 18 commits into from
Nov 21, 2024

Conversation

jung0115
Copy link
Member

@jung0115 jung0115 commented Oct 5, 2024

➡️ 문제 풀이 코드

🔗 문제 링크

프로그래머스 | 시뮬레이션 - 주차 요금 계산(Lv.2)

주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다.
image
image

  • 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
    • 0000번 차량은 18:59에 입차된 이후, 출차된 내역이 없습니다. 따라서, 23:59에 출차된 것으로 간주합니다.
  • 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
  • 누적 주차 시간이 기본 시간이하라면, 기본 요금을 청구합니다.
  • 누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구합니다.
    • 초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림합니다.
    • ⌈a⌉ : a보다 작지 않은 최소의 정수를 의미합니다. 즉, 올림을 의미합니다.
      주차 요금을 나타내는 정수 배열 fees, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어집니다. 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

✔️ 소요된 시간

1시간 30분

✨ 수도 코드

우선 입력 데이터를 파싱하는 작업부터 해줬습니다!
HH:MM 형식의 시간을 분단위 정수로 바꾸고, IN인지 OUT인지는 true, false로 저장해줬습니다.

data class Record (
    val time: Int,
    val carNum: Int,
    val isIn: Boolean
)

파싱해준 데이터는 이렇게 따로 Record 클래스를 만들어서 관리해줬습니다!

그리고 데이터를 순회하면서
입차(IN)인 경우, 차량 번호와 입차 시간을 HashMap에 기록했습니다.
출차(OUT)인 경우, HashMap에 저장된 입차 시간을 가져와 주차 시간을 계산하고, HashMap에 저장되어있던 입차 기록을 삭제했습니다.
한 차량이 어려번 입출차를 반복했을 수도 있기 때문에 차량번호 기준으로 주차 시간을 누적해서 기록해줬습니다

그리고 누적된 시간을 기준으로 요금을 계산하고, 차량 번호 순으로 정렬해줬습니다!
요금 계산은 기본 시간을 초과하면 초과된 시간에서 단위 시간당 추가요금을 계산해줬습니다
처음에는 한번 입출차 할 때마다 주차 요금을 계산해야 한다고 생각했는데, 기본 시간이 주차 1회당이 아닌 하루당 주어지는 것이었습니다 이 부분에 주의하면서 문제를 풀어나간 것 같습니다!

✅ 최종 코드

import java.util.HashMap

data class Record (
    val time: Int,
    val carNum: Int,
    val isIn: Boolean
)

class Solution {
    fun solution(fees: IntArray, records: Array<String>): IntArray {
        val sortRecords: MutableList<Record> = mutableListOf()
        
        // 주어진 기록을 파싱해서 Record 리스트로 변환
        for(record: String in records) {
            val current = record.split(" ")
            
            val timeSplit = current[0].split(":")
            val time: Int = timeSplit[0].toInt() * 60 + timeSplit[1].toInt()
            val carNum: Int = current[1].toInt()
            val isIn: Boolean = current[2] == "IN"
            
            sortRecords.add(Record(time, carNum, isIn))
        }
        
        // 입차 중인 차량들의 입차 시간을 저장하는 맵
        val inCars: HashMap<Int, Int> = HashMap()
        // 자동차 번호별 총 주차 시간을 저장하는 맵
        val parkingTimes: HashMap<Int, Int> = HashMap()
        
        // 각 레코드를 처리
        for(record: Record in sortRecords) {
            if (record.isIn) {
                // 입차 시 입차 시간을 기록
                inCars[record.carNum] = record.time
            } else {
                // 출차 시 주차 시간을 계산하고 누적
                val inTime: Int = inCars.remove(record.carNum) ?: 0
                val parkingTime = record.time - inTime
                parkingTimes[record.carNum] = parkingTimes.getOrDefault(record.carNum, 0) + parkingTime
            }
        }
        
        // 출차하지 않은 차량은 23:59에 출차된 것으로 간주
        val endTime = 23 * 60 + 59
        for((carNum, inTime) in inCars) {
            val parkingTime = endTime - inTime
            parkingTimes[carNum] = parkingTimes.getOrDefault(carNum, 0) + parkingTime
        }
        
        // 자동차 번호 순으로 결과를 계산
        val result: MutableList<Pair<Int, Int>> = mutableListOf()
        for((carNum, parkingTime) in parkingTimes) {
            var cost: Int = fees[1] // 기본 요금
            val overTime = parkingTime - fees[0]
            
            // 기본 시간을 넘은 경우 추가 요금을 계산
            if (overTime > 0) {
                cost += (overTime / fees[2]) * fees[3]
                if (overTime % fees[2] > 0) {
                    cost += fees[3]
                }
            }
            
            result.add(Pair(carNum, cost))
        }
        
        // 자동차 번호 순으로 정렬 후 요금만 반환
        return result.sortedBy { it.first }.map { it.second }.toIntArray()
    }
}

📚 새롭게 알게된 내용

Copy link
Member

@janghw0126 janghw0126 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제는 완벽하게 이해했는데, 머릿속에 있는 걸 구현해 나가기가 정말 쉽지 않았습니다..
정미님의 수도 코드에 언급된 것처럼 기본 시간이 주차 1회당이 아닌 하루당 주어진다는 것을 생각하지 않고 삽질만 계속하다가 결국 풀이를 참고했네요 ㅎㅎ

저는 차량별 이용 시간을 딕셔너리로 저장하고, 출차 이력이 없는 경우 마지막에 23:59를 추가로 저장해 주었습니다. 이후 딕셔너리를 key로 접근하기 위해서 차량번호를 정렬한 배열을 추가로 만들어주었고, 차량번호별로 탐색해서 소요시간을 계산하였습니다.

from collections import defaultdict
import math

def solution(fees, records):
    car_times = defaultdict(int)  # 차량별 누적 주차 시간을 저장
    in_times = {}  # 입차 시간을 기록
    
    # 기록 처리
    for record in records:
        time, car_num, action = record.split()
        time = int(time[:2]) * 60 + int(time[3:])  # 시간을 분 단위로 변환

        if action == "IN":
            in_times[car_num] = time
        else:
            car_times[car_num] += time - in_times.pop(car_num)  # 출차 후 누적 시간 계산
    
    # 출차 기록이 없는 차량 23:59 출차 처리
    for car_num, time in in_times.items():
        car_times[car_num] += 1439 - time  # 1439는 23:59를 분 단위로 변환한 값

    # 차량 번호순으로 정렬하고 요금 계산
    answer = []
    for car_num in sorted(car_times):
        total_time = car_times[car_num]
        if total_time <= fees[0]:
            answer.append(fees[1])
        else:
            extra_time = total_time - fees[0]
            extra_fee = math.ceil(extra_time / fees[2]) * fees[3]
            answer.append(fees[1] + extra_fee)

    return answer

정미님의 깔꼼쓰리한 설명과 코드에 감탄하구 갑니다!🤩 정말정말 대단하십니당👍

@jung0115 jung0115 removed the request for review from wonjunYou November 21, 2024 13:28
@jung0115 jung0115 removed the request for review from LJEDD2 November 21, 2024 13:28
@jung0115 jung0115 merged commit 82a3469 into main Nov 21, 2024
@jung0115 jung0115 deleted the 16-jung0115 branch November 21, 2024 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants