반응형
문제 출처
https://school.programmers.co.kr/learn/courses/30/lessons/92341
문제 풀이 힌트
01. 주어진 records 배열을 순회하면서 내가 원하는 정보의 형태로 저장할 것이다.
=> cars라는 객체 생성 후, 차량번호를 key로 설정하고 값으로는 "누적시간"과 IN일 때 임시로 시간(OUT일 땐 저장되어있는 IN 값과 시간 차이를 구하고 누적시간에 더해줄 것임)을 저장할 것.
02. 출차 하지 않은 차량이 있다면 23:59 로 누적시간을 구해줘야 한다.
03. 내가 정리한 cars 객체로 누적시간에 따른 요금을 계산하고, 배열의 형태로 return 할 것.
정답 풀이 코드
function solution(fees, records) {
const cars = {}; // 주차된 차량 정보를 저장할 객체
// 01. records 배열 순회하면서 내가 원하는 정보의 형태로 값을 저장
records.forEach(r => {
const [time, carNum, action] = r.split(' '); // 시간, 차량 번호, 입차/출차 여부 분리
if (!(carNum in cars)) { //carNum을 key로 저장
// 차량이 객체에 없으면 초기화
cars[carNum] = { time: 0, in: [] }; // 누적시간을 time의 값으로, IN일 때 시간을 임시로 저장할 in의 배열
}
if (action === 'IN') {// 입차인 경우
const [m, s] = time.split(':');
cars[carNum].in = [+m * 60 + +s]; // in의 값으로 임시로 시간을 저장한다.
} else { // 출차인 경우
const [m, s] = time.split(':');
const spendTime = (+m * 60 + +s) - cars[carNum].in.shift(); //in에 저장되어있는 값을 빼서(입차시간임) 출차시간과의 차이를 구한다.
cars[carNum].time += spendTime; // time에 총 주차 시간 누적
}
});
// 출차하지 않은 차량 체크
Object.entries(cars).forEach(([carNum, record]) => {
if (!record.in.length) return; // 입차 기록이 없으면 건너뜀
record.time += 1439 - record.in.shift(); // 23:59는 1439시간임 거기서 입차 시간을 빼준다.
});
//차 번호에 따른 누적시간이 저장되어있는 객체를 sort 함수로 낮으번호 부터 정렬한 후, 주차 요금 계산한 값을 새로운 배열을 반환할 것임
return Object.keys(cars).sort().map(carNum => {
if (cars[carNum].time <= fees[0]) return fees[1]; // 기본 시간 내에 주차한 경우
const time = cars[carNum].time - fees[0]; // 초과 시간 계산
return fees[1] + (Math.ceil(time / fees[2]) * fees[3]); // 초과 요금 계산 후 반환
});
}
Only 문제 풀이 코드
function solution(fees, records) {
const cars = {};
records.forEach(r => {
const [time, carNum, action] = r.split(' ');
if(!(carNum in cars)){
cars[carNum] = {time: 0, in: []}
}
if(action === 'IN'){
const [m, s] = time.split(':');
cars[carNum].in = [+m * 60 + +s];
}
else {
const [m, s] = time.split(':');
const spendTime = (+m * 60 + +s) - cars[carNum].in.shift();
cars[carNum].time += spendTime;
}
});
// 출차안한차량 체크
Object.entries(cars).forEach(([carNum, record]) => {
if(!record.in.length) return;
record.time += 1439 - record.in.shift();
});
return Object.keys(cars).sort().map(carNum => {
//요금계산
if(cars[carNum].time <= fees[0]) return fees[1];
const time = cars[carNum].time - fees[0];
return fees[1] + (Math.ceil(time / fees[2]) * fees[3]);
});
}
알고가는 ppoint
00. Object.entires(cars)로 가져오는 [carNum, record]의 모습
01.
02. 런타임 에러 나는 코드(내가 작성한 코드) )
function solution(fees, records) {
let carRecords = new Map();
let answer = [];
for(let i=0; i<records.length; i++){
const [time, num, inout] = records[i].split(' ');
if(!carRecords.has(num)){
carRecords.set(num, {carnum:num, total: 0, temp: 0, state: ""})
}
if(inout === 'IN'){
carRecords.get(num).temp = time;
carRecords.get(num).state = "IN";
}else if(inout === 'OUT'){
carRecords.get(num).total += calculate(carRecords.get(num).temp, time);
carRecords.get(num).state = "OUT";
}
}
for(let record of carRecords){
const [carnum, total, temp, state] = record
if(record.inout === "IN"){
carRecords.get(carnum).total += calculate(carRecords.get(num).temp, "23:59");
carRecords.get(carnum).state = "OUT";
}
}
function calculate(entryTime, exitTime) {
var entry = entryTime.split(":");
var exit = exitTime.split(":");
var entryMinutes = parseInt(entry[0]) * 60 + parseInt(entry[1]);
var exitMinutes = parseInt(exit[0]) * 60 + parseInt(exit[1]);
// Calculate parking time in minutes
var parkingTime = exitMinutes - entryMinutes;
return parkingTime;
}
function calculateParking(total){
let answer = 0;
if(total > fees[0]){
answer += fees[1];
answer += Math.ceil((total-fees[0])/fees[2]) * fees[3];
}else{
answer += fees[1]
}
return answer;
}
//OUT으로 끝나있으면 __계산하기 IN으로 끝나있으면 out23:59 계산해주기
for(let record of carRecords){
if(record.state === "OUT"){
let totalCal = calculateParking(record.total);
answer.push([record.carnum, totalCal]);
}
}
answer = answer.sort((a[0], b[0]) => {
return a[0]- b[0];
});
let answer2 = [];
for(let ans of answer){
answer2.push(ans[1]);
}
}
런타임 에러를 수정하기 위해 코드를 변경하겠습니다. 먼저 맵(Map)을 순회할 때 맵의 엔트리를 가져와야 합니다. 또한, 새로운 변수에 결과를 할당하지 않았기 때문에 결과를 반환하거나 다른 용도로 사용되지 않는 문제가 있습니다. sort 부분도 에러 수정. 아래는 수정된 코드입니다.
function solution(fees, records) {
let carRecords = new Map();
let answer = [];
for(let i=0; i<records.length; i++){
const [time, num, inout] = records[i].split(' ');
if(!carRecords.has(num)){
carRecords.set(num, {carnum:num, total: 0, temp: 0, state: ""})
}
if(inout === 'IN'){
carRecords.get(num).temp = time;
carRecords.get(num).state = "IN";
}else if(inout === 'OUT'){
carRecords.get(num).total += calculate(carRecords.get(num).temp, time);
carRecords.get(num).state = "OUT";
}
}
for(let record of carRecords.entries()){
const [carnum, recordData] = record;
if(recordData.state === "IN"){
carRecords.get(carnum).total += calculate(carRecords.get(carnum).temp, "23:59");
carRecords.get(carnum).state = "OUT";
}
}
function calculate(entryTime, exitTime) {
var entry = entryTime.split(":");
var exit = exitTime.split(":");
var entryMinutes = parseInt(entry[0]) * 60 + parseInt(entry[1]);
var exitMinutes = parseInt(exit[0]) * 60 + parseInt(exit[1]);
// Calculate parking time in minutes
var parkingTime = exitMinutes - entryMinutes;
return parkingTime;
}
function calculateParking(total){
let answer = 0;
if(total > fees[0]){
answer += fees[1];
answer += Math.ceil((total-fees[0])/fees[2]) * fees[3];
}else{
answer += fees[1]
}
return answer;
}
//OUT으로 끝나있으면 __계산하기 IN으로 끝나있으면 out23:59 계산해주기
for(let record of carRecords.values()){
if(record.state === "OUT"){
let totalCal = calculateParking(record.total);
answer.push([record.carnum, totalCal]);
}
}
answer = answer.sort((a, b) => {
return a[0]- b[0];
});
let answer2 = [];
for(let ans of answer){
answer2.push(ans[1]);
}
return answer2;
}
반응형
'알고리즘 문제 풀기' 카테고리의 다른 글
헷갈리는 객체 키와 값 가져오기 (for...in 반복문 /Object.keys() ) (0) | 2024.03.22 |
---|---|
프로그래머스 : 신고 결과 받기 - javascript(구현 , Map) (0) | 2024.03.21 |
dfs, 완전탐색, 백트래킹 관련 지식 정리 (0) | 2024.03.21 |
프로그래머스: 두 큐 합 같게 만들기 - javascript(시간복잡도 고려하는 구현문제) (1) | 2024.03.18 |
백준 1912: 연속합 - javascript(dp) (0) | 2024.03.17 |