[Problem Solving] 프린터

Sean·2023년 1월 13일
0

Problem Solving

목록 보기
28/130

문제

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

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

통과한 풀이

아이디어

  • 문제에서는 우선순위 리스트만 주어지고 문서의 고유 번호가 없으므로, 주어진 location에 해당하는 문서가 최종적으로 몇 번째로 출력되는지 알기 위해서는 객체 등을 활용해서 고유번호와 우선순위를 모두 저장한다. (info 배열)
  • info 배열을 돌면서 출력된 문서들은 info 배열을 빠져나가 printed 배열에 차곡차곡 쌓인다.
  • info[0]이 현재 빠져나갈지 말지를 결정해줘야 하는 문서이고, 이것의 우선순위보다 더 큰 우선순위의 문서가 이 뒤에 있다면 출력되지 못한다. 이것의 우선순위보다 더 큰 우선순위가 있는지를 판단하는 방법으로 나는 info 배열에서의 우선순위의 최댓값을 구했고, 다음과 같이 while문을 돌면서 처리해주었다.
    1. 문서들은 반드시 모두 printed 배열로 옮겨질 것이므로, while의 탈출 조건은 info 배열에 아무것도 남지 않았을 때로 잡아주었다.
    2. 이 최댓값이 info[0].pri와 다르다면 info[0]의 우선순위보다 큰 우선순위의 문서가 존재한다는 뜻이므로 다시 대기열의 맨 뒤로 push
    3. info[0].pri와 구한 최댓값이 같다면 이 문서의 우선순위가 제일 높은 것이므로, 출력될 수 있다. 즉, printed 배열로 이동.
  • 최종적으로 몇 번째로 출력되는지는 printed 배열에서 몇 번째인지 구하면 되고, 이는 Array.prototype.findIndex() 함수에 문제에서 주어진 locationprinted에 있는 문서들 중 고유번호가 같은 것을 찾는 판별식을 넣어주면 구할 수 있다.

코드

function solution(priorities, location) {
    var answer = 0;
    var maxpri;
    var info = [];
    var printed = [];
    
    priorities.forEach((p, idx) => {
        info.push({no: idx, pri: p});
    });
    
    while(info.length) {
        maxpri = info[0].pri;
        info.forEach(el => maxpri = el.pri > maxpri ? el.pri : maxpri);
        
        if(maxpri > info[0].pri)
            info.push(info.shift());
        else
            printed.push(info.shift());
    }
    
    answer = printed.findIndex(elem => elem.no === location) + 1;
    return answer;
}

또 다른 방법

  • 나는 info[0]의 우선순위보다 큰 것이 그 뒤에 있는지를 찾아보기 위해 info 배열의 전체에서 우선순위의 최댓값을 구하였는데, Array.prototype.find()를 쓰면 굳이 최댓값을 찾을 필요가 없다!!!

    💡 Array.prototype.find()
    some() 메서드는 배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 테스트합니다. 만약 배열에서 주어진 함수가 true을 반환하면 true를 반환합니다. 그렇지 않으면 false를 반환합니다. 이 메서드는 배열을 변경하지 않습니다.

코드

훨씬 간단해졌다!!!!!

function solution(priorities, location) {
    var answer = 0;
    var maxpri;
    var info = [];
    var printed = [];
    
    priorities.forEach((p, idx) => {
        info.push({no: idx, pri: p});
    });
    
    while(info.length) {
        if(info.some(el => el.pri > info[0].pri))
            info.push(info.shift());
        else
            printed.push(info.shift());
    }
    
    answer = printed.findIndex(elem => elem.no === location) + 1;
    return answer;
}
profile
여러 프로젝트보다 하나라도 제대로, 깔끔하게.

0개의 댓글