본문 바로가기
👋국비 후기 모음👋 (이력도 확인 가능!)
개발/코테 준비

[JS] 프로그래머스 - 프린터

by 킴뎁 2022. 2. 17.
728x90
반응형

내 풀이

function solution(pri, loc) {
	let prIndex = pri.map((a, index) => [a, index + 1]);
	let prCopy = prIndex.slice();
	let obj = [];
    
	while (prIndex.length > 0) {
		for (let i = 0; i < prIndex.length; i++) {
			if (prIndex[0][0] < prIndex[i][0]) {
				let first = prIndex.shift();
				prIndex.push(first);
				i = 0;
			}
		}
		obj.push(prIndex.shift());
	}
    
	for (let i = 0; i < obj.length; i++) {
		if (prCopy[loc] === obj[i]) {
			return i + 1;
		}
	}
}

 

해설

한 5시간 걸쳐서 풀어냈다. 좋은 풀이는 아닌거 같다만 뭐 어찌했든 풀어냈다가 중요한거니까..

나만의 풀이를 설명해본다.

이 문제를 한 10분정도 보고 이해했다.... 고 착각을 했다. 그래서 더 오래 걸렸던 것 같다.

뭔가 수학 공식을 쓴다던가 하는 건 없었다. 손으로 마구 적어가면 풀었다는...

 

단순히 생각하면 문서의 중요도 순서대로 오름차순하면 되는 문제인데 거기서 추가로 바뀌기 전의 순서를 기억해야한다. 그래서 접근한 방식이 2차원 배열이다. 전에 풀었던 해시 문제인 '위장'과 비슷한 방식으로 접근했다.

 

**예제 #2로 설명

function solution(pri, loc) { //pri = [ 1, 1, 9, 1, 1, 1 ]
    let prIndex = pri.map((a, index) => [a, index+1]);
    let prCopy = prIndex.slice();
    let obj = [];
    
    console.log(prIndex);   //[ [ 1, 0 ], [ 1, 1 ], [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ]
    console.log(prCopy);    //[ [ 1, 0 ], [ 1, 1 ], [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ]
    
	...
    
}

우선 map함수로 index를 포함하는 2차원 배열 prIndex를 만들어 준다.

prIndex[?][0] = 중요도 / prIndex[?][1] = location(loc)를 나타내는 인덱스.

그런 prIndex를 slice()로 깊은 복사를 한 배열이 prCopy.

prCopy는 초기 배열을 보여주고 obj는 순서를 다 바꾼 후의 결과를 나타낼 배열이다.

마지막엔 이 둘을 비교해 답을 얻어낼 예정이다.

반응형

 

function solution(pri, loc) {
    
	...

    console.log(prIndex);   // [ [ 1, 0 ], [ 1, 1 ], [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ]
    console.log(prCopy);    // [ [ 1, 0 ], [ 1, 1 ], [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ]
    
    while(prIndex.length > 0) {
        for(let i=0; i<prIndex.length; i++) {
            if(prIndex[0][0]<prIndex[i][0]) {
                let first = prIndex.shift();
                prIndex.push(first);
                i = 0;
            }
        }
        obj.push(prIndex.shift());
    }
    
    console.log(prIndex);	// []
    console.log(obj);		// [ [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 0 ], [ 1, 1 ] ]
   
   	...
    
}

이 부분을 어떻게 설명해야할까 고민이 된다.

차근차근 해보자. 최대한 이해할 수 있게끔 설명해보겠다.

설명하기 전 요약해보자면 문제에 나와있는 방식 그대로 순서를 바꾼 후 가장 큰 중요도가 나오면 인쇄(배열에서 제거)하고 

그 요소를 obj에 담아줘서 최종적으론 obj에는 인쇄한 순서대로 요소들이 담길 예정이다.

  • line8 - prIndex의 길이가 0이 될 때까지 while문을 돌릴 예정.
  • line10 - prIndex[?][0]는 앞서 말했듯이 중요도를 나타낸다. prIndex[0][0] = 가장 앞에 있는 문서 J의 중요도. 
  •     ㄴ '대기목록(prIndex)에서 J보다 중요도가 높은 문서가 하나라도 존재하면' -> prIndex[0][0]<prIndex[i][0]
  • line11 - prIndex.shift(); <- shift함수는 배열의 가장 작은 요소를 제거하고 제거한 요소를 반환하는 함수이다. 
  •     ㄴ shift()로 prIndex의 맨 앞 요소를 제거하고 그 요소를 first에 할당
  • line12 - 제거된 맨 앞 요소(first)를 prIndex 맨 뒤에 push().
  • line13 - i는 다시 0으로 초기화.
  • 왜? prIndex의 첫번째 요소가 이미 뒤로 간 상태이고 다시 새로운 첫번째 요소와 나머지 요소를 비교해야하므로. 
  • 그렇게 for문이 한 번 돌면 맨 앞 요소에는 중요도가 가장 큰 요소가 남는다.
  • line16 - prIndex의 첫번째 요소이자 가장 높은 중요도를 가지고 있는 요소를 제거(shift())함과 동시에 obj에 push();
  •     ㄴ 그렇게 prIndex의 길이가 0이 될 때까지 반복하고나면 최종적으로 obj에 문서들이 몇번째로 인쇄되는지 담게 된다.
  • obj를 보면 배열 뒤의 숫자들이 처음 location을 나타내게 된다.
  • line18 - prIndex는 전부 인쇄되어 빈 배열이 된 것을 확인할 수 있다.

 

function solution(pri, loc) {
    
    ..
    
    console.log(prCopy);    // [ [ 1, 0 ], [ 1, 1 ], [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ]
    console.log(obj);		// [ [ 9, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 0 ], [ 1, 1 ] ]
    for(let i=0; i<obj.length; i++) {
        if(prCopy[loc] === obj[i]) {
            return i+1;
        }
    }
}

이제 처음 대기목록인 prCopy와 obj를 비교해주면 끝.

구하고자 하는 location에 있었던 문서 prCopy[loc]와 obj[i]와 일치하면

return은 1부터 시작하므로 해당 인덱스인 i의 +1를 return해주면 된다.


다른 사람 풀이

function solution(priorities, location) {
    var list = priorities.map((t,i)=>({
        my : i === location,
        val : t
    }));
    var count = 0;        
    while(true){
        var cur = list.splice(0,1)[0];        
        if(list.some(t=> t.val > cur.val )){
            list.push(cur);                        
        }
        else{            
            count++;
            if(cur.my) return count;
        }
    }
}

some()을 처음 봤다. some()으로 조건을 줘서 맞는 요소가 나오면 true를 반환하는 함수이다. 대략적으로 설명해보자면 list에 첫번째 요소를 cur에 저장하고 cur보다 큰 요소 t가 나오면 list에 cur를 push해주는 코드이다.

이 코드는 굳이 list에서 shitf()를 해주지 않고 count로 계산하는 방식..? 나도 굳이 shift를 사용하면서 꼭 써야할까 의문점은 들었지만 적용은 못했는데 이런식으로 짜면 좋구나 생각했다.


풀면 풀수록 js의 기초를 쌓게 된다. 내가 그동안 js를 잘 모르고 사용했구나 매번 깨닫는다.

 

https://programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린

programmers.co.kr

반응형
👋국비 후기 모음👋 (이력도 확인 가능!)

댓글