N

(프로그래머스 KAKAO JS)주차 요금 계산 본문

프로그래머스 알고리즘/KAKAO

(프로그래머스 KAKAO JS)주차 요금 계산

naeunchan 2022. 2. 6. 15:45
728x90
반응형

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

 

코딩테스트 연습 - 주차 요금 계산

[180, 5000, 10, 600] ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"] [14600, 34400, 5000]

programmers.co.kr

 

 

변수)

우선 fees 배열에서 [기본 시간, 기본 시간 요금, 단위 시간, 단위 시간 요금]으로 값을 저장했다.

inCars는 차가 들어온 시간을 저장하는 Map,

outCars는 차가 나간 시간을 저장하는 Map이다.

carsNumber는 차 번호를 오름차순으로 저장하기 위한 배열.

 

1)

먼저 records 배열을 순회하면서 차의 입차, 출차 시간을 저장한다.

공백을 기준으로 문자열을 나눠 각각 [시간, 차번호, 차 상태]로 저장한다.

 

carsNumber에 number를 무조건 넣어주고, 나중에 set으로 변환해 중복 번호를 없애고 오름차순으로 정렬한다.

이후 state가 "IN"이라면 입차했다는 뜻이므로 inCars에 key = number, value = time으로 저장한다.

state가 "IN"이 아니라면 출차했다는 뜻이기 때문에 출차 시간 - 입차 시간을 구해 outCars에 저장해야 한다.

 

이를 구하기 위해서는 inCars에서 차 번호에 따른 시간을 가져와 ":"을 기준으로 시와 분을 분해한다.

또한, 출차 시간은 time으로 이미 저장되어 있기 때문에 time도 ":"을 기준으로 분해한다.

[inHour, inMinute] = [입차 시, 입차 분].

[outHour, outMinute] = [출차 시, 출차 분].

 

입차 시간과 출차 시간을 모두 분 단위로 계산을 하고,

outCars에서 number에 해당하는 value를 가져와 savedTime 변수에 저장한다.

(만약 outCars에 값이 없다면 최초 출차이기 때문에 savedTime = 0이 되도록 || 연산을 사용해 저장)

 

변수 세팅이 끝났으면 outCars에 key = number, value = (savedTime + (outTotal - inTotal))으로 저장한다.

또한, 출차가 끝났기 때문에 inCars에서 number를 delete 해준다.

 

2)

records 배열의 순회가 끝났다면 남아있는 입차된 차를 모두 23:59에 출차시켜야 한다.

inCars에 남아있는 값들은 출차가 안되었다는 뜻이 된다.

이 또한 위와 비슷한 과정으로 처리한다.

 

inCars 맵을 순회하여 입차 시, 입차 분을 ":"로 구분하여 분해.

outCars에서 해당 차 번호의 누적 시간을 savedTime 변수에 저장.

다시 outCars에 savedTime + (1439 - (입차 시 * 60 - 입차 분))으로 갱신한다.

(1439 = 23 * 60 + 59, 23:59를 분 단위로 계산)

 

 

3)

orderedNumbers는 carsNumber 배열을 set으로 변환시켜 중복된 번호를 없애고, 이를 오름차순으로 정렬한 값을 저장한 배열이다.

 

이 배열을 이용해 outCars에 저장된 누적 시간을 요금 계산하여 answer에 넣으면 정답을 구할 수 있다.

 

const solution = (fees, records) => {
    const answer = [];
    const [limitTime, feePerLimit, minute, feePerMinute] = fees;
    const inCars = new Map();
    const outCars = new Map();
    const carsNumber = [];
    
    for(const record of records){
        const [time, number, state] = record.split(" ");
        
        carsNumber.push(number);
        
        if(state === "IN"){
            inCars.set(number, time);
        } else{
            const [inHour, inMinute] = inCars.get(number).split(":");
            const [outHour, outMinute] = time.split(":");
            const inTotal = (parseInt(inHour) * 60) + parseInt(inMinute);
            const outTotal = (parseInt(outHour) * 60) + parseInt(outMinute);
            const savedTime = outCars.get(number) || 0;
            
            outCars.set(number, savedTime + (outTotal - inTotal));
            inCars.delete(number);
        }
    }
    
    for(const [key, value] of inCars){
        const [inHour, inMinute] = value.split(":");
        const savedTime = outCars.get(key) || 0;
        
        outCars.set(key, savedTime + ((60 * 23) + 59) - ((parseInt(inHour) * 60) + parseInt(inMinute)));
    }
    
    const orderedNumbers = [...new Set(carsNumber)].sort((a, b) => a - b);
    
    for(const number of orderedNumbers){
        const totalTime = outCars.get(number);
        const totalFee = totalTime <= limitTime ? feePerLimit : (feePerLimit + (Math.ceil((totalTime - limitTime) / minute) * feePerMinute));
        
        answer.push(totalFee);
    }
    
    return answer;
}
728x90
반응형