일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.
예를 들어, 4개의 문서(A, B, C, D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다.
내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다.
현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.
현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다.
인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다.
location은 0 이상 (현재 대기목록에 있는 작업 수 - 1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다.
priorities | location | return |
---|---|---|
[2, 1, 3, 2] | 2 | 1 |
[1, 1, 9, 1, 1, 1] | 0 | 5 |
function solution2() {
let answer = 0;
let candidate;
let max;
const queue = priorities.map((priority, id) => ({ id, priority }));
for (let i = 0; i < priorities.length; i++) {
max = Math.max(...queue.map((item) => item.priority));
candidate = queue.shift();
while (candidate.priority !== max) {
queue.push(candidate);
candidate = queue.shift();
}
answer += 1;
if (candidate.id === location) {
break;
}
}
return answer;
}
function solution2() {
let answer = 0; // 지금까지 인쇄된 문서의 숫자!
let candidate; // 인쇄할지 말지 궁금한 첫 번째 문서(후보)
let max; // 가장 높은 우선순위의 값
const queue = priorities.map((priority, id) => ({ id, priority })); // 객체 만들기
for (let i = 0; i < priorities.length; i++) {
// 인쇄할 문서인 candidate을 선정
max = Math.max(...queue.map((item) => item.priority));
// queue에서 값을 빼서 candidate에 넣는다
candidate = queue.shift();
// 그 candidate의 priority가 가장 중요한 max가 아니면
while (candidate.priority !== max) {
// queue에 다시 넣고 새 candidate를 뺀다
queue.push(candidate);
candidate = queue.shift();
}
answer += 1;
if (candidate.id === location) {
break;
}
}
// [1,1,9,1,1,1]
// => [{ id: 0, priority: 1}, { id: 1, priority: 1}, { id: 2, priority: 9}, ...]
return answer;
}
테스트 1 〉 통과 (0.53ms, 29.8MB)
테스트 2 〉 통과 (0.53ms, 30MB)
테스트 3 〉 통과 (0.38ms, 30.1MB)
테스트 4 〉 통과 (0.16ms, 30.2MB)
테스트 5 〉 통과 (0.12ms, 30MB)
테스트 6 〉 통과 (0.32ms, 30.1MB)
테스트 7 〉 통과 (0.17ms, 30MB)
테스트 8 〉 통과 (0.34ms, 30.1MB)
테스트 9 〉 통과 (0.26ms, 30.1MB)
테스트 10 〉 통과 (0.31ms, 30.2MB)
테스트 11 〉 통과 (0.28ms, 30.1MB)
테스트 12 〉 통과 (0.34ms, 30.2MB)
테스트 13 〉 통과 (0.42ms, 30.3MB)
테스트 14 〉 통과 (0.27ms, 30.3MB)
테스트 15 〉 통과 (0.14ms, 29.9MB)
테스트 16 〉 통과 (0.14ms, 29.8MB)
테스트 17 〉 통과 (0.48ms, 30.1MB)
테스트 18 〉 통과 (0.13ms, 29.9MB)
테스트 19 〉 통과 (0.45ms, 30.4MB)
테스트 20 〉 통과 (0.36ms, 30MB)
candidate
와 max
변수를 생성한다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
return answer;
};
priorities
배열을 id가 담긴 객체 값으로 변환해준다. 여담이지만 처음 이 알고리즘 풀이를 할 때 id
값을 할당해주지 않아서 이후에 for문 내부에서 많은 삽질을 하게 되었다..💧 아무튼 이후에 매개 변수로 받은 또 다른 값인 location(나의 인쇄 위치 값)과 비교하여 함수를 종료해야 하기 때문에 map
메소드를 사용하여 객체 형태로 값을 변환해서 반환해준다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
return answer;
};
priorities
배열의 길이만큼 반복(for
문 사용)해서 중요도가 높은 문서 순대로 인쇄하고, 인쇄한 문서는 사라지게 만든 뒤 answer에 count를 해줄 것이다. 그리고 중요도에서 밀린 문서는 다시 인쇄 대기군 배열의 뒤의 순서에 붙이도록 한다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
for(let i = 0; i < priorities.length; i++){ }
return answer;
};
printed
에서 Math.max()
메소드를 사용하여 가장 큰 값(인쇄 중요도가 제일 높은 값)을 max
변수에 할당하고, 인쇄 대기군 printed
에서 가장 앞에 있는 순서의 값을 shift()
메서드로 잘라내서 인쇄 대기 목록 최우선 후보군인 candidate
에 할당한다. function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
for(let i = 0; i < priorities.length; i++){
max = Math.max(...printed.map((item) => item.priority));
candidate = printed.shift();
}
return answer;
};
candidate
)의 priority
값이 max
와 동일한 값(최대 우선 값)이 나타나기 전까지 while
문을 사용해서, 해당 값이 나타나기 전까지 인쇄 대기 목록 최우선 후보군인 candidate
를 인쇄 대기 목록인 printed
배열에 push()
메서드를 사용하여 뒤의 순서에 붙이고, candidate
에 현재 남아있는 인쇄 대기 목록인 printed
의 맨 앞자리 값을 잘라내서(shift()
) 할당하는 것을 반복한다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
for(let i = 0; i < priorities.length; i++){
max = Math.max(...printed.map((item) => item.priority));
candidate = printed.shift();
while(candidate.priority !== max){
printed.push(candidate);
candidate = printed.shift();
}
}
return answer;
};
for
이 돌 때마다 answer
에 +1을 카운팅 해준다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
for(let i = 0; i < priorities.length; i++){
max = Math.max(...printed.map((item) => item.priority));
candidate = printed.shift();
while(candidate.priority !== max){
printed.push(candidate);
candidate = printed.shift();
}
answer += 1;
}
return answer;
};
location
(나의 인쇄물)위치가 인쇄 대기 후보군 candidate
의 id
와 동일하면 answer는 더이상 카운팅 되지 않고, 반복문은 종료한다.function solution(priorities, location) {
let answer = 0;
let candidate;
let max;
const printed = priorities.map((v, i) => ({id: i, priority: v }));
for(let i = 0; i < priorities.length; i++){
max = Math.max(...printed.map((item) => item.priority));
candidate = printed.shift();
while(candidate.priority !== max){
printed.push(candidate);
candidate = printed.shift();
}
answer += 1;
if(candidate.id === location) {
break;
}
}
return answer;
};