코딩테스트 JS 큐: 상담 창구 대기열 명령 처리

2026.09.10·수정 2026.09.13·약 10분·작성: 해비·블로그 소개

독립 창작 문제: 상담 창구 대기열

도착한 순서를 지키며 고객을 호출하고 대기 인원을 출력합니다. 같은 이름의 고객도 각각 별도 방문으로 보관합니다.

큐의 FIFO 구조 개념 표지

이 문제는 BlogFlow 학습용으로 독립 창작했습니다. 외부 문제의 지문·예시·테스트를 복제하지 않았습니다.

개념 연결: 큐와 FIFO 가이드

문제

비어 있는 상담 창구에 명령이 순서대로 주어집니다. ARRIVE 이름은 고객을 대기열 뒤에 추가합니다. CALL은 가장 먼저 온 고객 이름을 출력한 뒤 대기열에서 제거하며, 비어 있으면 EMPTY를 출력합니다. COUNT는 현재 인원 수를 출력합니다. 이름이 같아도 도착한 횟수만큼 별도 항목으로 취급합니다.

입력·출력·제약

첫 줄은 정수 Q(0~100,000), 다음 Q줄은 정의된 명령입니다. 이름은 공백 없는 1~40 코드포인트 문자열입니다. CALL과 COUNT 결과를 각 한 줄로 출력하며 결과가 하나도 없으면 아무것도 출력하지 않습니다. 명령과 이름 사이에는 공백 하나를 사용합니다.

예시 1

입력:

7
ARRIVE 민수
ARRIVE 수지
CALL
ARRIVE 준호
COUNT
CALL
CALL

출력:

민수
2
수지
준호

예시 2: 빈 상태

입력:

2
CALL
COUNT

출력:

EMPTY
0

힌트

아직 읽지 않은 첫 위치 head를 움직이세요. 빈 큐는 값이 undefined인지가 아니라 head와 배열 길이가 같은지로 판단합니다.

정답 코드와 해설 펼치기

Node.js 24 CommonJS용 코드입니다. 전체를 queue-helpdesk-problem.cjs로 저장하고 예시 입력을 input.txt에 UTF-8로 저장합니다. 아래 명령은 셸에 맞게 하나를 골라 사용하세요.

PowerShell 7 (UTF-8 파이프):

Get-Content -Raw -Encoding UTF8 .\input.txt | node .\queue-helpdesk-problem.cjs

macOS / Linux Bash:

node queue-helpdesk-problem.cjs < input.txt
function createQueue() {
  let items = [];
  let head = 0;
  return {
    enqueue(value) {
      items.push(value);
    },
    dequeue() {
      if (head === items.length) {
        return { done: true };
      }
      const value = items[head];
      items[head] = undefined;
      head += 1;
      if (head === items.length) {
        items = [];
        head = 0;
      } else if (head >= 1024 && head * 2 >= items.length) {
        items = items.slice(head);
        head = 0;
      }
      return { done: false, value };
    },
    size() {
      return items.length - head;
    },
  };
}

function solve(input) {
  const text = input.trim();
  if (!text) {
    return '';
  }
  const lines = text.split(/\r?\n/);
  const count = Number(lines[0]);
  const queue = createQueue();
  const output = [];
  for (let i = 1; i <= count; i++) {
    const [command, name] = lines[i].split(' ');
    if (command === 'ARRIVE') {
      queue.enqueue(name);
    } else if (command === 'CALL') {
      const result = queue.dequeue();
      output.push(result.done ? 'EMPTY' : result.value);
    } else if (command === 'COUNT') {
      output.push(String(queue.size()));
    }
  }
  return output.join('\n');
}

module.exports = { solve };

if (require.main === module) {
  const input = require('node:fs').readFileSync(0, 'utf8');
  process.stdout.write(solve(input));
}

명령과 상태 변화

명령 처리 뒤 목록 출력
ARRIVE 민수 민수 없음
ARRIVE 수지 민수 → 수지 없음
CALL 수지 민수
ARRIVE 준호 수지 → 준호 없음
COUNT 수지 → 준호 2
CALL, CALL 빈 큐 수지, 준호

왜 이 구현으로 맞는가

정답 파일은 createQueue 선언부터 solve, 표준 입력 처리까지 포함합니다. 다른 가이드 파일을 require하지 않습니다. Node 내장 fs만 표준 입력을 읽는 데 사용합니다. 유효 입력 계약을 가정하는 연습 풀이이며 잘못된 명령·누락 줄을 진단하는 파서는 아닙니다.

solve는 첫 줄의 명령 수를 읽고 정확히 그만큼 순회합니다. ARRIVE에는 반환할 결과가 없으므로 output에 넣지 않습니다. CALL은 dequeue의 done으로 빈 상태를 구분하고 COUNT는 size를 문자열로 바꿉니다. output.join("\n")은 결과 사이에만 줄바꿈을 넣어 Q=0일 때 빈 문자열을 반환합니다.

각 명령 직전 큐의 유효 구간에는 아직 호출하지 않은 방문만 도착 순으로 남아 있습니다. enqueue가 뒤에 추가하고 dequeue가 앞의 한 항목만 제거하므로 명령 처리 뒤에도 이 불변식은 유지됩니다. COUNT가 전체 items.length를 읽으면 이미 호출한 슬롯까지 세므로 반드시 size를 사용합니다.

head가 커지면 소비한 앞부분이 물리 배열에 남습니다. dequeue는 사용한 슬롯의 참조를 먼저 끊고, 충분히 많은 슬롯을 소비했을 때 남은 값만 복사합니다. 한 압축은 O(K)이지만 그 비용을 앞선 제거들에 나누면 큐 연산은 분할 상환 O(1)입니다.

시간·공간과 문자열 비용

큐에 남은 최대 항목 수를 K라 하면 큐 구조만의 공간은 O(K+1024)입니다. 그러나 이 프로그램은 전체 입력 문자열, 줄 배열, 출력 배열과 마지막 결합 문자열까지 메모리에 보관합니다. 입력 문자 수 S, 출력 문자 수 R, 명령 수 Q를 포함한 전체 추가 저장은 O(S+R+Q+K), K≤Q이므로 O(S+R+Q)입니다. 따라서 프로그램 전체 공간을 O(K)라고 쓰면 입력·출력을 빠뜨립니다. 문자열 처리까지 포함한 총시간은 통상적 동적 배열 모델에서 O(S+R+Q) 상환이며, 큐 연산만 따로 보면 O(Q) 상환입니다.

표본을 직접 확인하는 코드

다음 코드를 queue-helpdesk-check.cjs로 저장한 뒤 node queue-helpdesk-check.cjs로 실행하세요. assert가 일치하면 출력 없이 종료하고, 결과가 다르면 예외가 발생합니다. 같은 폴더의 정답 파일을 가져오는 이 블록은 풀이 본체가 아니라 표본 확인용입니다.

const assert = require('node:assert/strict');
const { solve } = require('./queue-helpdesk-problem.cjs');

const input = "7\nARRIVE 민수\nARRIVE 수지\nCALL\nARRIVE 준호\nCOUNT\nCALL\nCALL";
const expected = "민수\n2\n수지\n준호";
assert.equal(solve(input), expected);
assert.equal(solve("2\nCALL\nCOUNT"), "EMPTY\n0");
assert.equal(solve('0'), '');

연결 학습

큐와 FIFO 가이드에서 메서드별 불변식을 확인하세요. 공식 문제 사이트의 백준 10845 큐는 다른 계약을 가진 추가 연습입니다. 공식 링크 확인일: 2026년 9월 10일.

풀이 전에 확인할 순서

  1. 입력값과 출력값을 한 문장으로 다시 적습니다.
  2. 반복할 대상과 비교·저장할 값을 정합니다.
  3. 필요한 자료구조와 시간복잡도를 예상합니다.
  4. 코드를 보기 전에 손으로 작은 예제를 계산합니다.
힌트: 코딩테스트 JS 큐: 상담 창구 대기열 명령 처리

정답 코드를 바로 따라 쓰기보다, 본문에서 값이 갱신되는 조건과 반복 범위를 먼저 찾으세요. 반복 한 번마다 반드시 유지되어야 하는 값이 무엇인지 적으면 풀이의 중심 변수를 고르기 쉽습니다.

테스트 확인

  • 가능한 가장 작은 입력
  • 같은 값이나 문자가 반복되는 입력
  • 정답이 처음 또는 마지막 위치에서 결정되는 입력
  • 입력 제한에 가까운 경우의 실행 시간

확인 결과: 본문의 예제뿐 아니라 위 경계 사례에서도 예상값과 실제 출력이 같아야 풀이가 완료됩니다.

이 글이 도움이 되었나요?

조회 중

코딩테스트 JavaScript 학습 순서

필수 49개 · 전체 49개

읽음 기록 관리

전체 과정 목차 (49개)
  1. 필수 길잡이 · 코딩테스트 JS 자료구조 로드맵: 배열, 해시, 스택, 투 포인터 순서
  2. 필수 학습 · 세 수 중 최솟값 JavaScript 조건문 풀이 정리
  3. 필수 학습 · 삼각형 판별하기 JavaScript 풀이
  4. 필수 학습 · 연필 개수 JavaScript 풀이
  5. 필수 학습 · 1부터 N까지 합 출력하기 JavaScript 풀이
  6. 필수 학습 · 최솟값 구하기 JavaScript 풀이|배열 순회와 비교 갱신 원리
  7. 필수 학습 · 홀수 JavaScript 풀이: 조건 판별과 결과 처리 정리
  8. 필수 학습 · 10부제 JavaScript 풀이: 끝자리 비교로 위반 차량 수 세기
  9. 필수 학습 · A를 #으로 JavaScript 풀이: 문자열 순회와 치환
  10. 필수 학습 · 문자 찾기 JavaScript 풀이: 문자열 순회로 개수 세기
  11. 필수 학습 · 대문자 찾기 JavaScript 풀이
  12. 필수 학습 · 대문자로 통일 JavaScript 풀이
  13. 필수 학습 · 대소문자 변환 JavaScript 풀이
  14. 필수 학습 · 일곱 난쟁이 JavaScript 풀이: 두 명을 제외하는 완전탐색
  15. 필수 학습 · 코딩테스트 JS Map 풀이: 학급 회장 득표수 세기
  16. 필수 학습 · 코딩테스트 JS 스택 풀이: 올바른 괄호 검증하기
  17. 필수 학습 · 코딩테스트 JS 스택 풀이: 괄호문자 제거하기
  18. 필수 학습 · 코딩테스트 JS 스택 풀이: 크레인 인형뽑기 처리법
  19. 필수 학습 · 코딩테스트 JS 스택 풀이: 후위식 연산 계산하기
  20. 필수 학습 · 코딩테스트 JS 스택 풀이: 쇠막대기 레이저 절단 개수 세기
  21. 필수 학습 · 코딩테스트 JS 투 포인터 풀이: 두 정렬 배열 합치기
  22. 필수 학습 · 코딩테스트 JS 투 포인터 풀이: 공통 원소 추출하기
  23. 필수 학습 · 코딩테스트 JS 슬라이딩 윈도우 풀이: 최대 매출 구간 합 계산하기
  24. 필수 학습 · JavaScript 투 포인터: 합이 M인 연속 부분수열 개수
  25. 필수 학습 · 코딩테스트 JS 해시 풀이: 모든 아나그램 찾기
  26. 필수 학습 · 가장 긴 문자열 JavaScript 풀이
  27. 필수 학습 · 가운데 문자 출력 JavaScript 풀이
  28. 필수 학습 · 중복문자제거 JavaScript 풀이
  29. 필수 학습 · 코딩테스트 JS 고급: 최소 힙으로 다익스트라 최단 경로 구하기
  30. 필수 학습 · 코딩테스트 JS Union-Find: 연결 성분 수와 크기 구하기
  31. 필수 학습 · 코딩테스트 JS Trie: 접두사에 맞는 단어 수 세기
  32. 필수 학습 · 코딩테스트 JS Fenwick Tree: 값 갱신과 구간 합 처리
  33. 필수 학습 · 코딩테스트 JS 세그먼트 트리: 단일 대입과 구간 합
  34. 필수 학습 · 코딩테스트 JS LRU 캐시: 지도 타일 재사용 기록
  35. 필수 학습 · 코딩테스트 JS AVL 트리: 기준 이상 최솟값 찾기
  36. 필수 학습 · 코딩테스트 JS 큐: 상담 창구 대기열 명령 처리 현재 글
  37. 필수 학습 · 코딩테스트 JS 연결 리스트: 재생 대기 목록 관리
  38. 필수 학습 · JavaScript 원형 덱 연습: 최근 기록 창과 되돌리기
  39. 필수 학습 · JavaScript 해시 테이블 연습: 정규화 문자열 빈도와 등장 순서
  40. 필수 학습 · JavaScript 트리 순회 연습: 깊이별 노드 묶기
  41. 필수 학습 · JavaScript BST 연습: 닫힌 구간의 중복 키 보고서
  42. 필수 학습 · JavaScript 최소 힙 연습: 동률 순서를 지키는 작업 스케줄러
  43. 필수 학습 · JavaScript 그래프 연습: 연결 구역 크기를 작은 순서로 출력하기
  44. 필수 학습 · 중복단어제거 JavaScript 풀이
  45. 필수 학습 · TypeScript 이진 탐색 연습: 숫자 카드 존재 여부 확인
  46. 필수 학습 · 큰 수 출력하기 JavaScript 풀이
  47. 필수 학습 · 보이는 학생 JavaScript 풀이
  48. 필수 학습 · 가위바위보 JavaScript 풀이
  49. 필수 학습 · 점수계산 JavaScript 풀이

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기