View

 

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, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어집니다.차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

fees[0] = 기본 시간(분) / fees[1] = 기본 요금(원) / fees[2] = 단위 시간(분) / fees[3] = 단위 요금(원)

  • 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
    • 0000번 차량은 18:59에 입차된 이후, 출차된 내역이 없습니다. 따라서, 23:59에 출차된 것으로 간주합니다.
  • 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
  • 누적 주차 시간이 기본 시간이하라면, 기본 요금을 청구합니다.
  • 누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구합니다.
    • 초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림합니다.
    • ⌈a⌉ : a보다 작지 않은 최소의 정수를 의미합니다. 즉, 올림을 의미합니다.

 

문제 해결 아이디어

차량 번호마다 IN, OUT을 기록하기 위해 Map을 사용했다. 차량 번호를 key로 하는 것이다.

IN이 들어오는 순간 만약 해당 차량 번호가 map에 없다면 차량 번호를 key로 하고 value를 {in: 시간}으로 추가해 주었다.

그리고 OUT인 경우 value를 꺼내서 시간을 계산해 준다. 시간을 계산하는 calMin 함수는 몇 분 동안 주차했는지 리턴해 준다.

예외(?)는 다시 주차하러 오는 경우다. 따라서 OUT인 경우 해당 시간을 다시 map에 {min: 분}으로 추가해 두었다. 그렇다면 또 IN이 들어오는 순간 map에는 해당 차량 번호가 존재할 것이고, 똑같이 value에 {in: 시간}을 넣어 주겠지만 min도 존재한다. 

그렇기 때문에 OUT인 경우에 min이 존재하는지 한번 더 검사를 해주어 존재한다면 min에 calMin에서 리턴받은 값을 더해주어야 한다.

 

차량 번호가 작은 자동차부터 요금을 담아야 했기 때문에 map을 다시 array로 풀고 차량 번호대로 sort하여 다시 map으로 만들었다. (좋은 방법일까??)

 

마지막으로 요금을 계산하는데 출차가 안 찍혀 있는 경우가 있을 수 있으므로 그런 경우에 한번 더 out을 23:59로 해서 분을 계산해 주었다. 주차한 시간이 기본 시간보다 작다면 기본요금을 push하고 그렇지 않은 경우에는 조건대로 계산해서 push했다.

 

완성된 코드

function solution(fees, records) {
    var answer = [];
    const map = new Map();
        let inTime, out;
    for (let i = 0; i < records.length; i++) {
        const content = records[i].split(" ");
        if (content[2] === "IN") {
            if(map.has(parseInt(content[1]))) {
                let beforeMin = map.get(parseInt(content[1]));
                map.set(parseInt(content[1]), {in: content[0], min: beforeMin});
            } else {
                map.set(parseInt(content[1]), {in: content[0]});
            }
        } else {
            inTime = map.get(parseInt(content[1])).in;
            const min = map.get(parseInt(content[1])).min;
            if (min) {
                map.set(parseInt(content[1]), calMin(inTime, content[0]) + min);
            } else {
                map.set(parseInt(content[1]), calMin(inTime, content[0]));
            }
        }
    }
    const sortedMap = new Map([...map.entries()].sort((a, b) => a[0] - b[0]));
    
    let min;
    for (let info of sortedMap.values()) { 
        if (info.in) {
            if(info.min) {
                 min = calMin(info.in, '23:59') + info.min;
            }
            else {
                min = calMin(info.in, '23:59');
            }
        } else {
            min = info;
        }
        if (min <= fees[0]) {
            answer.push(fees[1]);
        } else {
            answer.push(Math.ceil((min - fees[0]) / fees[2])*fees[3] + fees[1]);
        }
    }

    return answer;
}

const calMin = (start, fin) => {
    const inArr = start.split(":");
    const outArr = fin.split(":");
    const calMin = (parseInt(outArr[0]) * 60 + parseInt(outArr[1])) 
            - (parseInt(inArr[0]) * 60 + parseInt(inArr[1]));
    return calMin;
}
Share Link
reply
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30