[Queue] 프린터기

박채은·2022년 11월 22일
0

코딩테스트

목록 보기
2/52

문제

[코플릿 - 프린터]


배열로 구현한 코드

public class Solution {
    public int queuePrinter(int bufferSize, int capacities, int[] documents) {
        int t = 1; // 시간
        int index = 0;
        int[] buffer = new int[bufferSize];

        while (true) {
            // 출력하기 -> 버퍼에서 삭제
            if (buffer[buffer.length - 1] != 0) {
                buffer[buffer.length - 1] = 0;
            }
            // 문서 한칸 이동
            for (int i = buffer.length - 1; i >= 1; i--) {
                buffer[i] = buffer[i - 1];
            }
            buffer[0] = 0;
            // 문서 추가 - 용량이 가능한지 체크
            if (index < documents.length) { // document가 모두 입력되고, 해당 문서가 빠져나갈 때는 실행되지 않도록 조건 추가
                if ((Arrays.stream(buffer).sum() + documents[index] <= capacities)) {
                    buffer[0] = documents[index++];
                }
            }
            // 탈출 조건 - 입력된 문서가 모두 빠져나가면 break
            if (Arrays.stream(buffer).filter(e -> e == 0).count() == bufferSize) {
                break;
            }
            t++;
        }
        return t;
    }
}

나는 Queue를 배열로 구현하였다.

  • 배열의 0으로 문서가 enqueue가 되고, buffer.length-1에서 문서가 dequeue된다.
  • 문서의 크기는 1 이상이기 때문에, 해당 칸이 비었음을 0으로 표현해주었다.

문서를 추가하고, 문서가 한 칸씩 이동하고, 출력되는 것이 모두 같은 시간에 병렬적으로 일어나기 때문에 다음과 같이 세가지 동작으로 나누어 코드를 작성했다.

우선 출력할 수 있는 문서가 있다면(buffer[buffer.length-1]가 비어있지 않다면), 출력해준다.
그 뒤에 한 칸씩 앞당겨 준다.
한 칸씩 이동하다보면, buffer[0]이 비게 된다.
새로운 문서를 넣었을 때, capacities를 넘지 않으면 추가하고, 넘는다면 넘지 않을 때까지 기다렸다가 추가해준다.

모든 문서를 buffer에 넣었어도, buffer에서 출력되지 않고 남아있는 경우가 있기 때문에 탈출 조건은 buffer가 비었을 때가 되어야 한다.

문제의 예시와 동일한 경우에, 6초에서 buffer는 [0,6] 상태가 된다.
buffer에 모든 문서가 들어갔지만, 아직 6Kib 문서는 출력되지 않았으므로 buffer에서 출력되는 시점인 8초가 정답이다.


LinkedList로 구현한 코드

다른 분은 배열이 아닌 LinkedList로 Queue를 구현하셨다.
자바에서는 Queue로 주로 LinkedList를 사용하기 때문에 이 방법으로도 코드를 짜보았다.

public class Solution {
    public int queuePrinter(int bufferSize, int capacities, int[] documents) {
        int t = 0; // 시간
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < bufferSize; i++) {
            queue.add(0);
        }
        // 첫번째 값은 반복문 밖에 넣어줌
        queue.poll();   // bufferSize에 맞게, 빈 칸을 하나 빼고 새로운 문서를 넣어줌
        queue.add(documents[0]);
        documents = Arrays.copyOfRange(documents, 1, documents.length);  // buffer에 입력된 문서는 배열에서 지워주기
        t++;

        while (documents.length != 0 || queue.stream().mapToInt(e -> e).sum() != 0) {   // buffer와 배열이 모두 빌 때까지 반복
            if (documents.length != 0) { // buffer에 넣을 문서가 남아 있는 경우
                queue.poll();          // 출력하기 + 한 칸씩 앞으로 댕기기
                if (queue.stream().mapToInt(e -> e).sum() + documents[0] <= capacities) { // 새로운 문서를 추가할 수 있는 경우
                    queue.add(documents[0]);
                    documents = Arrays.copyOfRange(documents, 1, documents.length); // buffer에 입력된 문서는 배열에서 지워주기
                } else {
                    queue.add(0);
                }
            } else { // buffer에 넣을 문서가 남아 있지 않은 경우
                queue.poll(); // buffer에 남아있는 문서들을 출력하기
                queue.add(0);
            }
            t++;
        }
        return t;
    }
}

0개의 댓글