[Programmers] 프린터 (JS)

nRecode·2021년 1월 29일
0

Algorithm

목록 보기
32/48

문제

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

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 함수를 작성해주세요.

입출력 예
priorities: [1, 1, 9, 1, 1, 1]
location: 0
return: 5

접근

우선 순위 순으로 프린터를 먼저해야하기에 priorities[0]번째가 max값이면 print하고 그렇지 않으면 다시 priorities.push[0] 후 priorities.unshift()한다.

전체적인 흐름은 위와 같지만 추가로 내가 인쇄를 요청한 문서가 몇번째에 인쇄되는지 알아야하기 때문에 push와 unshift를 priorities와 index가 합쳐진 배열을 사용한다.

그리고 다 print가 완료되면, 내가 찾고자하는 location과 일치하는 인덱스를 가진 값의 순서를 return 한다.

풀이

function solution(priorities, location) {
    var answer = 0;
 
    let newpri = [];
    let print = [];
    
    priorities.forEach((val, idx) => {
        newpri.push([val,idx]);
    });

    let length = priorities.length;
    
    while(length){
        let max = Math.max(...priorities);
        if(newpri[0][0] === max){
            print.push(newpri[0]);
            length--;
            priorities.shift();
            newpri.shift();
        }else{
            newpri.push(newpri[0]);
            priorities.push(priorities[0]);
            newpri.shift();
            priorities.shift();
        }
    }
    
    print.forEach((val, idx) => {
        if(val[1] === location) answer = idx + 1;
    })
    
    return answer;
}

통과는 하였지만 priorities를 이용해 만든 배열 newpri와 priorities를 while과정에서 함께 사용하여서 아쉬움이 남는다.

다른 풀이 방법

function solution(priorities, location) {
    let answer = 0;
    let tasks = priorities.map((v,i)=>({ 
        lo : i === location,    
        val: v                  
    }));
    /*
        기존의 배열형태에서 현재 위치하고있는 인덱스정보를 같이 갖고있는 객체로 저장
        location은 현재 대기목록의 위치 여기 예제에서는 배열의 3번째 값.
     [ 
        { lo: false, val: 2 },
        { lo: false, val: 1 },
        { lo: true, val: 3 },
        { lo: false, val: 2 } 
     ]
    */
    while(true){
        let cur = tasks.splice(0,1)[0];         //현재 처리하고자 하는 일을 빼낸다. splice 메서드는 원본 배열의 값을 바꿈.
        if(tasks.some(t=>t.val > cur.val)){       //현재 처리하고자 하는 일보다 더 높은 우선순위의 일이 있는지 비교
            tasks.push(cur);                    //더 높은 우선순위가 존재할 때, 현재 하고자 하는 일은 맨 뒤로 밀어둠.
        }
        else {                                  //현재 하고자 하는 일이 가장 높은 우선순위일 때
            answer++;                           //answer 값에 +1을 한다.(인쇄순서를 카운트)
            if(cur.lo) return answer;           //그 일이 문제에서 현재 위치로 주어진 부분일 때 answer 값을 리턴.
        }
    }
}
profile
안정성, 확장성 있는 서버를 구축하고 가꾸는 개발자를 목표로 공부하고 있습니다. 🤔🤔🤔🤔 부족하기에 맞지 않는 내용이 있을 수 있습니다. 가감없이 피드백 해주시면 정말 감사하겠습니다..🙏

0개의 댓글