[프로그래머스][스택&큐][JS] 프린터(7/5 업데이트)

Teasan·2022년 7월 2일
0

Algorythm

목록 보기
10/17
post-thumbnail

프린터


문제 설명

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.

  1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다.
  2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
  3. 그렇지 않으면 J를 인쇄합니다.

예를 들어, 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로 표현합니다.


입출력 예

prioritieslocationreturn
[2, 1, 3, 2]21
[1, 1, 9, 1, 1, 1]05

풀이 코드

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;
}

출력

  • 1
  • 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++) {
    // 인쇄할 문서인 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)

풀이 순서 (복습/업데이트:7월5일)

  • 먼저, 인쇄 대기 목록 최우선 후보군과 중요도가 가장 큰 문서를 임시로 할당할 candidatemax 변수를 생성한다.
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 (나의 인쇄물)위치가 인쇄 대기 후보군 candidateid 와 동일하면 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;
};

⚡️ Reference


✍🏻 programmers 문제 출처 - 프린터


profile
일단 공부가 '적성'에 맞는 개발자. 근성있습니다.

0개의 댓글