[lv.2] 주차 요금 계산 | 프로그래머스
[lv.2] 주차 요금 계산 | 프로그래머스
📋 [ 프로그래머스 ] 시리즈 몰아보기 (17)
✏️ (lv.2) : 주차 요금 계산
주차장의 요금표와 차량이 들어오고 나간 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 한다. 아래는 하나의 예시를 나타낸다.
요금표
기본 시간(분) 기본 요금(원) 단위 시간(분) 단위 요금(원) 180 5000 10 600 입/출차 기록
시간(H:M) 차량 번호 내역 05:34 5961 입차 06:00 0000 입차 06:34 0000 출차 07:59 5961 출차 07:59 0148 입차 18:59 0000 입차 19:09 0148 출차 22:59 5961 입차 23:59 5961 출차 차량별 주차 요금
차량 번호 누적 주차 시간(분) 주차 요금(원) 0000 34 + 300 = 334 5000 + (334 - 180) / 10 _ 600 = 14600 0148 670 5000 + (670 - 180) / 10 _ 600 = 34400 5961 145 + 1 = 146 5000 - 어떤 차량이 입차된 후 출차 내역이 없다면
23:59에 출차된 것으로 간주한다. - 00:00 ~ 23:59까지의 입/출차 내역을 바탕으로 누적 주차 시간을 계산해 요금을 일괄정산 한다.
- 누적 주차 시간이
기본 시간이하라면기본 요금을 청구한다. - 누적 주차 시간이
기본 시간을 초과하면기본 요금+ 초과한 시간 _단위 시간_단위 요금을 청구한다.- 초과한 시간이
단위 시간으로 나누어 떨어지지 않으면올림한다.
- 초과한 시간이
- 어떤 차량이 입차된 후 출차 내역이 없다면
주차 요금을 나타내는 정수 배열 fees, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어질 때 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하는 solution 을 작성하라.
fees의 길이 = 4- fees[0] =
기본 시간(분) - 1 ≤ fees[0] ≤ 1,439
- fees[1] =
기본 요금(원) - 0 ≤ fees[1] ≤ 100,000
- fees[2] =
단위 시간(분) - 1 ≤ fees[2] ≤ 1,439
- fees[3] =
단위 요금(원) - 1 ≤ fees[3] ≤ 10,000
- fees[0] =
- 1 ≤
records의 길이 ≤ 1,000records의 각 원소는"시각 차량번호 내역"형식의 문자열이다.시각,차량번호,내역은 하나의 공백으로 구분되어 있다.시각은 차량이 입차되거나 출차된 시각을 나타내며, HH:MM 형식의 길이 5인 문자열이다.HH:MM은 00:00부터 23:59까지 주어진다.- 잘못된 시각("25:22", "09:65" 등)은 입력으로 주어지지 않는다.
차량번호는 자동차를 구분하기 위한, `0'~'9'로 구성된 길이 4인 문자열이다.내역은 길이 2 또는 3인 문자열로,IN또는OUT이다.IN은 입차를,OUT은 출차를 의미한다.records의 원소들은 시각을 기준으로 오름차순으로 정렬되어 주어진다.records는 하루 동안의 입/출차된 기록만 담고 있으며, 입차된 차량이 다음날 출차되는 경우는 입력으로 주어지지 않는다.- 같은 시각에, 같은 차량번호의 내역이 2번 이상 나타내지 않는다.
- 마지막 시각(23:59)에 입차되는 경우는 입력으로 주어지지 않는다.
- 아래의 예를 포함하여, 잘못된 입력은 주어지지 않는다.
- 주차장에 없는 차량이 출차되는 경우
- 주차장에 이미 있는 차량(차량번호가 같은 차량)이 다시 입차되는 경우
객체를 이용해 차량의 입/출차 시간에 따른 주차 시간을 기록, 해당 객체를 순회하며 주차시간을 주어진 요금표에 맞게 정산하여 return한다.
- 객체
parkingTime을 선언한다. records를item으로 순회하며 다음 로직을 수행한다.item을split(" ")으로 분리하고 각각time,id,type으로 선언한다.- 이중
time을 또다시split(":")으로 분리하고 시간(h* 60) + 분(m)으로 값을 초기화한다. parkingtime[id]가 존재하지 않을 경우 해당 값을 0으로 초기화한다.type==="IN"인 경우parkingTime[id]의 값에 1439 -time을 더한 후 해당 결과값으로 초기화한다.type==="OUT"인 경우parkingTime[id]의 값에 1439 -time을 차감한 후 해당 결과값으로 초기화한다.- 1439 -
time을 수행하는 이유는 1439(=24*60-1)이고 입차 후 출차기록이 없을 경우 해당 값을 즉시 이용하기 위해서이다. 출차가 정상적으로 진행된다면 마찬가지로 1439 -time의 값을 연산에 이용하기에 본질적으로 주차시간을 계산함에 있어서 문제가 없게된다.
- 1439 -
- 배열
answer을 선언한다. parkingTime의 key와 value를 각각car,time이라 선언하고 해당 값을 이용해 객체를 순회하며 다음 로직을 수행한다.time{'<='}기본 시간인 경우time을기본 요금으로 초기화한다.- 그렇지 않을 경우 (
time-기본 시간) /단위 요금의 결과값을Math.ceil()메소드를 이용해 올림연산을 수행한 후time의 값으로 초기화한다. answer에 [car, time]을 push한다.
answer를sort()메소드를 이용해 각 원소의 첫번째 값(차량 번호)를 기준으로 정렬한 후.map()메소드를 이용해 차량요금만 추출하여 새로운 배열로 초기화 후 return 한다.
| 1 | // 개선판 |
| 2 | function betterSolution(fees, records) { |
| 3 | const parkingTime = {}; |
| 4 | records.forEach(item => { |
| 5 | let [time, id, type] = item.split(" "); |
| 6 | let [h, m] = time.split(":"); |
| 7 | time = h * 1 * 60 + m * 1; |
| 8 | if (!parkingTime[id]) parkingTime[id] = 0; |
| 9 | if (type === "IN") parkingTime[id] += 1439 - time; |
| 10 | if (type === "OUT") parkingTime[id] -= 1439 - time; |
| 11 | }); |
| 12 | const answer = []; |
| 13 | for (let [car, time] of Object.entries(parkingTime)) { |
| 14 | if (time <= fees[0]) time = fees[1]; |
| 15 | else time = Math.ceil((time - fees[0]) / fees[2]) * fees[3] + fees[1]; |
| 16 | answer.push([car, time]); |
| 17 | } |
| 18 | return answer.sort((a, b) => a[0] - b[0]).map(v => v[1]); |
| 19 | } |
| 20 | |
| 21 | // 처음 작성했던 코드 |
| 22 | function solution(fees, records) { |
| 23 | const answer = []; |
| 24 | const park = new Map(); |
| 25 | const parkingFee = new Map(); |
| 26 | const isPark = new Map(); |
| 27 | |
| 28 | records.forEach(item => { |
| 29 | let [time, car, state] = item.split(" "); |
| 30 | time = time.split(":").map(e => +e); |
| 31 | time = time[0] * 60 + time[1]; |
| 32 | |
| 33 | if (state === "IN") { |
| 34 | park.set(car, time); |
| 35 | isPark.set(car, true); |
| 36 | } else { |
| 37 | isPark.set(car, false); |
| 38 | parkingFee.set( |
| 39 | car, |
| 40 | parkingFee.get(car) + time - park.get(car) || time - park.get(car), |
| 41 | ); |
| 42 | } |
| 43 | }); |
| 44 | |
| 45 | for ([key, value] of isPark.entries()) { |
| 46 | if (value) { |
| 47 | parkingFee.set( |
| 48 | key, |
| 49 | parkingFee.get(key) + 24 * 60 - 1 - park.get(key) || |
| 50 | 24 * 60 - 1 - park.get(key), |
| 51 | ); |
| 52 | isPark.set(key, false); |
| 53 | } |
| 54 | answer.push(key); |
| 55 | } |
| 56 | |
| 57 | answer.sort((a, b) => a - b); |
| 58 | for ([car, time] of parkingFee.entries()) { |
| 59 | if (time > fees[0]) { |
| 60 | time = Math.ceil((time - fees[0]) / fees[2]); |
| 61 | answer[answer.indexOf(car)] = fees[1] + time * fees[3]; |
| 62 | } else { |
| 63 | answer[answer.indexOf(car)] = fees[1]; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | return answer; |
| 68 | } |
👨💻 관련 포스트
[lv.1] 대충 만든 자판 | 프로그래머스
[lv.1] 대충 만든 자판 | 프로그래머스
프로그래머스 lv.1 대충 만든 자판 풀이 with javascript. javascript 객체를 이용해 keymap에 존재하는 알파벳의 index를 기록하되 가장 최단거리에 해당하는 키캡의 index를 기록하여 통합된 자판을 생성하여 문제를 해결한다.
2023-05-28
[lv.1] 개인정보 수집 유효기간
[lv.1] 개인정보 수집 유효기간
프로그래머스 lv.1 개인정보 수집 유효기간 풀이 with javascript. 해당 문제에서 한달은 28일로 고정이다. 따라서 today와 privacies 각 원소(개인정보)의 날짜를 년, 월, 일에 각 단위에 해당하는 수 * 28을 수행하여 일 단위로 변환한 후 terms에 해당하는 수를 더해 문제를 해결한다.
2023-05-30
[lv.1] 성격 유형 검사하기 | 프로그래머스
[lv.1] 성격 유형 검사하기 | 프로그래머스
프로그래머스 lv.1 성격 유형 검사하기 풀이 with javascript. javascript의 객체를 이용해 성격 유형(이하 MBTI)별 획득 점수를 기록하고 MBTI의 value를 비교해 문제를 해결한다.
2023-06-01
💡 로그인 하지 않아도 댓글을 등록할 수 있습니다!