본문 바로가기

코딩테스트/programmers

주차 요금 계산

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

 

프로그래머스

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

programmers.co.kr

 

처음엔 아래 방식으로 계산했다.

 

시간 계산 편의를 위해 입/출차 시간을 분으로 변환 했다. (시간 * 60 + 분)

차량 번호를 기준으로 맵을 만들고,

입차시 입차 시간을 기록하고, 출차시 (출차 시간 - 입차시간)을 총 주차 시간에 더해준다.

입차기록만 있는 경우 23시59분을 출차로 계산해야하므로 마지막 단계에서 처리해준다.

 

import java.util.*;

class Solution {
    
    static int[] feesTable;
    
    public int[] solution(int[] fees, String[] records) {
        
        feesTable = fees;
        
        Map<String, Info> infos = new HashMap();
        for (String record : records) {
            
            Info info = Info.from(record);
            if (!infos.containsKey(info.carNumber)) {
                infos.put(info.carNumber, info);
            } else {
                Info history = infos.get(info.carNumber);
                history.update(info);
            }
            
        }
        
        return infos.entrySet().stream()
            .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
            .mapToInt(e -> e.getValue().fees())
            .toArray();
        
    }
    
    static class Info {
        
        static final int IN = 0;
        static final int OUT = 1;
        
        String carNumber;
        
        int time;
        int inOut;
        
        int duration;
        
        static Info from(String record) {
            Info vo = new Info();
            
            String[] split = record.split(" ");
            vo.carNumber = split[1];
            vo.time = time(split[0]);
            vo.inOut = split[2].equals("IN") ? IN : OUT;
            
            return vo;
        }
        
        static int time(String time) {
            String[] split = time.split(":");
            return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
        }
        
        void update(Info newInfo) {
            
            if (newInfo.inOut == IN) {
                this.time = newInfo.time;
                this.inOut = IN;
            } else {
                this.duration += (newInfo.time - this.time);
                this.time = 0;
                this.inOut = OUT;
            }
            
        }
        
        int fees() {
            
            int fees = feesTable[1];
            
            if (this.inOut != OUT) {
                this.duration += (23 * 60 + 59 - this.time);
            }
            
            int extra = Math.max(0, this.duration - feesTable[0]);
            
            fees += (((int) Math.ceil(1.0 * extra / feesTable[2])) * feesTable[3]);
            
            return fees;
        }

        
    }
    
    
    
}

 

 

그런데 다른 분 정답을 보니 입출차를 -+로 계산하는 분이 계시더라.. 천재인가..

그래서 아래처럼 다시 풀어봄

 

    import java.util.*;

    class Solution {

        final int endOfDay = 23 * 60 + 59;
        
        public int[] solution(int[] fees, String[] records) {

            Map<String, Integer> cars = new HashMap();
            
            for (String record : records) {
                
                String[] split = record.split(" ");
                
                int min = toMins(split[0]);
                
                String carNumber = split[1];
                
                int weight = split[2].equals("IN") ? -1 : 1;
                
                int duration = cars.getOrDefault(carNumber, 0);
                duration += (weight * min);
                cars.put(carNumber, duration);
                
            }
            
            return cars.entrySet().stream()
                .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
                .mapToInt(e -> {
                    
                    int fee = fees[1];
                    
                    int duration = e.getValue();
                    if (duration <= 0) duration += endOfDay;
                    
                    if (duration > fees[0]) {
                        fee += extraFee(duration, fees[0], fees[2], fees[3]);
                    }
                    
                    return fee;

            }).toArray();
            

        }
        
        // xx:xx 의 시간을 n분으로 변환
        int toMins(String time) {
            String[] split = time.split(":");
            return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
        }
        
        // 기본료를 제외한 추가 요금
        int extraFee(int duration, int freeTime, int unitTime, int unitFee) {
            return ((int) Math.ceil(1.0 * (duration - freeTime) / unitTime)) * unitFee;
        }


    }

'코딩테스트 > programmers' 카테고리의 다른 글

방문 길이  (0) 2023.10.25
땅따먹기  (0) 2023.10.25
더 맵게  (0) 2023.10.23
모음사전  (0) 2023.10.23
게임 맵 최단거리  (0) 2023.10.23