[프로그래머스(Programmers)] 주차 요금 계산 (java) /2022 KAKAO BLIND RECRUITMENT

2
post-thumbnail

안녕하세요. 오늘은 프로그래머스의 주차 요금 계산 문제를 풀어보겠습니다. 이 문제는 2022년도 KAKAO BLIND RECRUITMENT에서 출제되었습니다.


1) 문제 링크

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

2) 문제 풀이

✔ HashMap 두 개 생성

차량의 출차와 입차를 관리하는 HashMap(parkingLot)과 각 차량의 총 주차시간을 저장하는 HashMap(totalTimes)을 생성합니다.

parkingLot

key는 차량번호(Integer), value는 입차 시간(Date)입니다.

totalTimes

key는 차량번호(Integer), value는 총 주차시간(Integer)입니다.

✔ 입차, 출차 확인하며 각 차량의 총 주차 시간 구하기

차량의 입차와 출차를 확인하며 각 차량의 총 주차 시간을 구합니다. parkingLot hashMap에 주어진 차량번호가 저장되어 있다면 차량을 내보내야(출차) 하고, 저장되어 있지 않다면 차량을 들여보내야(입차) 합니다.

입차 로직

차량을 들여보낼 때는 별다른 로직이 필요 없습니다.

출차 로직

차를 내보낼 때는 차의 총 주차시간(totalTimes)을 업데이트 해야합니다. (출차 시간 - 입차 시간)을 totalTimes hashMap에 저장합니다. 만약 totalTimes hashMap에 이미 해당 차량이 주차한 시간이 저장되어 있다면, 이전 주차 시간에 새로운 주차 시간을 더해줍니다. 총 주차시간을 업데이트 한 후에는 parkingLot hashMap에서 차량번호를 remove합니다.

23:59분에 모든 차를 내보낸다

마지막까지(23:59까지) 안나간 차가 있으면 다 내보내야 합니다. 23:59분을 기준으로 출차 로직을 수행합니다.

✔ 한 차량이 내야 하는 총 요금 구하기

총 주차 시간을 토대로 총 요금을 구합니다. 만약 어떤 차의 총 주차시간이 기본시간(fees[0])을 넘지 않으면, 그냥 기본요금(fees[1])만 내면 됩니다.
추가로, (총 주차시간 - 기본 주차시간)에서 단위 시간을 나눈 나머지가 0이 아니면, 단위 요금을 한번 더 더해줍니다.

3) 전체 코드

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


class Solution {
    private static Map<Integer, Date> parkingLot;   //주차장 -> 입차, 출차 관리
    private static Map<Integer, Integer> totalTimes;   //시간 저장 map

    public int[] solution(int[] fees, String[] records) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

        parkingLot = new HashMap<>();
        totalTimes = new HashMap<>();

        for (String str : records) {
            //05:34 5961 IN
            String[] record = str.split(" ");
            Date time = sdf.parse(record[0]);
            int carNum = Integer.parseInt(record[1]);

            if(parkingLot.containsKey(carNum)) {
                findTotalTimes(carNum, time);

                parkingLot.remove(carNum);
            } else {
                parkingLot.put(carNum, time);
            }
        }

        //차 전부 다 내보내기
        if(!parkingLot.isEmpty()) {
            List<Integer> keySet = new ArrayList<>(parkingLot.keySet());
            Date outTime = sdf.parse("23:59");

            for (int key : keySet) {
                findTotalTimes(key, outTime);
                
                parkingLot.remove(key);
            }
        }

        return findTotalCharges(fees);
    }

    //한 차량이 주차한 총 시간 구하기
    private void findTotalTimes(int carNum, Date outTime) {
        Date inTime = parkingLot.get(carNum);
        long value = (outTime.getTime() - inTime.getTime())/60000;

        if (totalTimes.containsKey(carNum)) {
            value += totalTimes.get(carNum);
        }

        totalTimes.put(carNum, (int) value);
    }

    /*
    fees[0] : 기본 시간(분)  180
    fees[1] : 기본 요금(원)  5000
    fees[2] : 단위 시간(분)  10
    fees[3] : 단위 요금(원)  600
     */
     //한 차량이 내야 하는 총 요금 구하기
    private int[] findTotalCharges(int[] fees) {
        List<Integer> keySet = new ArrayList<>(totalTimes.keySet());
        Collections.sort(keySet);

        int[] answer = new int[keySet.size()];
        int basicTime = fees[0];
        int basicFee = fees[1];
        int unitTime = fees[2];
        int unitFee = fees[3];

        for (int i = 0; i < keySet.size(); i++) {
            int key = keySet.get(i);
            int timeValue = totalTimes.get(key);

            if(timeValue <= basicTime) {
                answer[i] = basicFee;
            } else {
                answer[i] = (timeValue - basicTime) / unitTime * unitFee + basicFee;
                if ((timeValue - basicTime) % unitTime != 0) {
                    answer[i] += unitFee;
                }
            }
        }

        return answer;
    }
}

0개의 댓글