뭐요

[프로그래머스] 주차 요금 계산 (JAVA) 본문

Problem Solving

[프로그래머스] 주차 요금 계산 (JAVA)

욕심만 많은 사람 2023. 6. 3. 16:18

https://school.programmers.co.kr/tryouts/71916/challenges

import java.util.*;

class Solution {
    private int DEFAULT_TIME, DEFAULT_FEE, UNIT_TIME, UNIT_FEE;
    private Map<String, String> map = new HashMap<>(); // 차량번호 to 입차시각
    private Map<String, Integer> parkingTimeMap = new HashMap<>();
    private Map<String, Integer> feeMap = new HashMap<>();
    
    public int[] solution(int[] fees, String[] records) {
        init(fees);
        
        // set 차량별 주차시간 총합
        StringTokenizer st;
        for(String str : records){
            st = new StringTokenizer(str);
            String time = st.nextToken();
            String carNo = st.nextToken();
            String type = st.nextToken();
            
            if(type.equals("IN")){
                map.put(carNo, time);
            }else if(type.equals("OUT")){
                String inTime = map.get(carNo);
                int sumTime = getSumMinute(inTime, time);
                parkingTimeMap.put(carNo, parkingTimeMap.getOrDefault(carNo, 0) + sumTime);
                map.remove(carNo);
            }
        }
        
        // 출차 안된 차량 set 주차시간 총합
        for(String key : map.keySet()){
            String inTime = map.get(key);
            int sumTime = getSumMinute(inTime, "23:59");
            parkingTimeMap.put(key, parkingTimeMap.getOrDefault(key, 0) + sumTime);
        }
        
        // 요금 계산 후 feeMap 삽입
        for(String carNo : parkingTimeMap.keySet()){
            int parkingTime = parkingTimeMap.get(carNo);
            int fee = getFee(parkingTime);
            
            feeMap.put(carNo, fee);
        }
            
        // 주차 번호 별 정렬
        List<Map.Entry<String, Integer>> list = new ArrayList<>(feeMap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2){
                return o1.getKey().compareTo(o2.getKey());
            }
        });
        
        // answer
        return getAnswer(list);
    }
    
    private int getFee(int parkingTime){
        if(parkingTime <= DEFAULT_TIME)
            return DEFAULT_FEE;
        
        // 기본요금에 대한 기본시간 차감
        int fee = DEFAULT_FEE;
        parkingTime -= DEFAULT_TIME;
        
        // 단위시간 별 요금 계산
        int multiple = parkingTime / UNIT_TIME;
        if(parkingTime % UNIT_TIME != 0)
            multiple++;
        fee += (multiple * UNIT_FEE);
        
        return fee;
    }
    
    private int getSumMinute(String inTime, String outTime){
        String[] inTimeToken = inTime.split(":");
        String[] outTimeToken = outTime.split(":");
        int differHour = Integer.parseInt(outTimeToken[0]) - Integer.parseInt(inTimeToken[0]);
        int differMinute = Integer.parseInt(outTimeToken[1]) - Integer.parseInt(inTimeToken[1]);
        
        if(differMinute < 0){
            differHour--;
            differMinute += 60;
        }
        
        return (differHour * 60) + differMinute;
    }
    
    private void init(int[] fees){
        DEFAULT_TIME = fees[0];
        DEFAULT_FEE = fees[1];
        UNIT_TIME = fees[2];
        UNIT_FEE = fees[3];
    }
    
    private void debugPrint(){
        System.out.println("map : " + map);
        System.out.println("parkingTimeMap : " + parkingTimeMap);
        System.out.println("feeMap : " + feeMap);
    }
    
    private int[] getAnswer(List<Map.Entry<String, Integer>> list){
        int[] answer = new int[list.size()];
        for(int i = 0 ; i < list.size(); i++){
            answer[i] = list.get(i).getValue();
        }
        
        return answer;
    }
}

빡구현

  • 코드 짤때마다 단위테스트 돌려가며 짜니까 중간에 틀린 부분 바로바로 알 수 있어서 아무래도 필수인 거 같음
  • 이런 유형의 빡구현 문제 풀면서 시간을 줄이려고 의식적인 노력이 필요함
  • 추후에 한번 더 풀면서 시간 줄이기

Retrospective

코드를 작성하기 전에 시간을 더 들여서라도 문제를 완벽하게 이해하는 것이 시간을 더 절약할 수 있는 방법임.

기존 코드 : records 배열을 순회하며 그때그때 주차장 요금 계산 (맞지 않는 경우)

수정 : records 배열을 순회하며 총 주차 시간 구한후 일괄로 주차장 요금 계산