준영이의 성장일기(FrontEnd)
프로그래머스 - 과제 진행하기 본문
<문제>
https://school.programmers.co.kr/learn/courses/30/lessons/176962?language=javascript
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제의 제한사항
3 ≤ plans의 길이 ≤ 1,000plans의 원소는 [name, start, playtime]의 구조로 이루어져 있습니다.
name : 과제의 이름을 의미합니다.
2 ≤ name의 길이 ≤ 10name은 알파벳 소문자로만 이루어져 있습니다. 또한 name이 중복되는 원소는 없습니다.
start : 과제의 시작 시각을 나타냅니다."hh:mm"의 형태로 "00:00" ~ "23:59" 사이의 시간값만 들어가 있습니다.
모든 과제의 시작 시각은 달라서 겹칠 일이 없습니다.과제는 "00:00" ... "23:59" 순으로 시작하면 됩니다.
즉, 시와 분의 값이 작을수록 더 빨리 시작한 과제입니다.playtime : 과제를 마치는데 걸리는 시간을 의미하며, 단위는 분입니다. 1 ≤ playtime ≤ 100playtime은 0으로 시작하지 않습니다.
배열은 시간순으로 정렬되어 있지 않을 수 있습니다.
진행중이던 과제가 끝나는 시각과 새로운 과제를 시작해야하는 시각이 같은 경우 진행중이던 과제는 끝난 것으로 판단합니다.
<문제 핵심>
이 문제는 로직의 흐름이 왜 이렇게 흘러가는지 파악해야한다.
일단 각 plans배열 요소마다 과목, 시작 시간, 소요시간 으로 구성되어 있었다. 일단 시간을 분으로 바꿔주는 함수를 적용하였다.
function timeToMin(time) {
const [hh, mm] = time.split(':').map(Number);
return hh * 60 + mm;
}
제일 중요했던 건 만약 기존의 태스크가 13:00에 끝나는 경우 새로운 태스크가 12:30에 시작한다면 기존의 태스크를 멈춘 다음 새로운 태스크를 진행해야한다. 이거는 문제 조건에 의거하면 알 수 있다.
새로운 과제를 시작할 시각이 되었을 때, 기존에 진행 중이던 과제가 있다면 진행 중이던 과제를 멈추고 새로운 과제를 시작합니다
그리고 만약 12:30에 시작한 태스크가 40분 후에 끝나고 13:10에 시작하는 태스크가 있다고 해보자. 아까 멈췄던 13:00에 끝나는 태스크, 그리고 13:10에 시작하는 태스크 중 먼저 수행해야 할거는 새로 시작하는 태스크이다.
<문제 풀이과정 및 순서도>
1. 시간을 분으로 바꿔주는 함수를 구현한다.
function timeToMin(time) {
const [hh, mm] = time.split(':').map(Number);
return hh * 60 + mm;
}
2. 위에 설명한 로직의 흐름을 코드로 구현한다.
✅ 가장 빠른 시간에 시작하는 과제부터 차례대로 처리할 수 있도록 역순으로 정렬한다.
✅ 만약 새로 시작되는 과제가 이전 과제의 종료 시간보다 빨리 시작한다면, 그 과제의 종료 시간을 현재 과제의 소요 시간만큼 뒤로 미룬다.(이게 사실 문제의 핵심으로 새로 들어오는 과제가 끝나야 중단했던 과제를 진행할 수 있기 때문이고 또한 충돌 방지를 위해서)
✅ stack 배열은 과제가 언제 끝나는지를 관리해주기 위해 이용하기
function solution(plans) {
const stack = [];
//과제가 언제 종료되는지를 관리
const sortedPlans = plans
.map(([subject, time, count]) => [subject, timeToMin(time), Number(count)])
.sort((a, b) => b[1] - a[1]);
while (sortedPlans.length) {
const [subject, time, count] = sortedPlans.pop()
//가장 빨리 시작하는게 나올 것임
stack.forEach((val, idx) => {
if(time < val[1]) {
stack[idx][1] += count;
}
})
//idx는 첨에 0으로 시작할 것
stack.push([subject, time+count])
}
const answer = stack.sort((a, b) => a[1] - b[1]).map(val => val[0]);
return answer;
}
<전체 코드>
function timeToMin(time) {
const [hh, mm] = time.split(':').map(Number);
return hh * 60 + mm;
}
function solution(plans) {
const stack = [];
//과제가 언제 종료되는지를 관리
const sortedPlans = plans
.map(([subject, time, count]) => [subject, timeToMin(time), Number(count)])
.sort((a, b) => b[1] - a[1]);
while (sortedPlans.length) {
const [subject, time, count] = sortedPlans.pop()
//가장 빨리 시작하는게 나올 것임
stack.forEach((val, idx) => {
if(time < val[1]) {
stack[idx][1] += count;
}
})
//idx는 첨에 0으로 시작할 것
stack.push([subject, time+count])
}
const answer = stack.sort((a, b) => a[1] - b[1]).map(val => val[0]);
return answer;
}
'코테 및 알고리즘' 카테고리의 다른 글
백준 js, Python - N과M(5) (3) | 2024.09.26 |
---|---|
프로그래머스 - 퍼즐 게임 챌린지 (0) | 2024.09.24 |
백준 js 1063번 (2) | 2024.09.18 |
백준 1183번 js (0) | 2024.09.08 |
프로그래머스 - 땅따먹기 (1) | 2024.09.07 |