Tiny Star
본문 바로가기
Dev Log/Kotlin

[코틀린] 복잡한 '연속 근무 방지' 로직, Queue(큐) 하나로 깔끔하게 해결하기

by 별터 2026. 1. 7.

이번 미션의 핵심 로직은 "비상 근무표를 짜되, 한 사람이 이틀 연속 근무할 수 없다"는 규칙을 지키는 것이었습니다. 만약 연속 근무가 발생하면, 다음 순번의 근무자와 순서를 바꿔야 합니다.

 

처음에는 직관적으로 생각나는 대로 코드를 짰지만, 곧 복잡한 `for`문과 `while`문의 늪에 빠지고 말았습니다. 어떻게 이 로직을 개선했는지, 그 리팩토링 과정을 공유합니다.


1. 초기 접근: 일단 배정하고, 나중에 고치자

 

처음에는 단순하게 생각했습니다.

  1. 순서대로 날짜에 사원을 다 집어넣는다.
  2. 처음부터 끝까지 훑으면서 "어? 얘 연속이네?" 싶으면 뒤의 사람과 바꾼다.
  3. 바꾸고 나서 또 겹칠 수 있으니, 문제가 없어질 때까지 `while(true)`로 계속 검사한다.
// 개선 전 코드 (의사 코드)
while (hasConsecutiveWorker(schedule)) {
    for (i in 0 until schedule.size - 1) {
        if (schedule[i] == schedule[i+1]) {
            swap(schedule, i+1, findNextWorker(schedule))
        }
    }
}

 

문제점

  • 비효율: 이미 배정된 스케줄을 몇 번이나 다시 훑어야 할지 모릅니다.
  • 복잡도: while 안에 for 안에 if... 들여쓰기(Depth)가 3단계, 4단계로 깊어집니다.
  • 가독성: 코드를 읽는 사람이 흐름을 파악하기 어렵습니다.

2. 사고의 전환: 넣기 전에 검사하자 (Queue 활용)

 

"이미 어지러진 방을 치우는 것보다, 물건을 놓을 때 제자리에 놓는 게 더 빠르지 않을까?"

이런 생각으로 자료구조 Queue(대기열)를 도입했습니다.

 

개선된 로직

  1. 평일 근무자 명단과 휴일 근무자 명단을 각각 Queue (LinkedList)에 넣습니다.
  2. 하루씩 날짜를 진행하며 근무자를 뽑습니다(poll).
  3. 검사: "방금 뽑은 사람이 어제 일한 사람인가?"
    • Yes: 그 사람을 다시 대기열 맨 앞(addFirst)에 잠깐 넣어두고, 그 다음 사람을 뽑습니다. (순서 교체 효과)
    • No: 그대로 근무 시킵니다.
  4. 근무한 사람은 대기열의 맨 뒤(addLast)로 보내 순번을 돌립니다.
// 개선된 코드 예시
val weekdayQueue = LinkedList(weekdayWorkers)
var previousWorker: Worker? = null

dayList.forEach { day ->
    var candidate = weekdayQueue.poll() // 1. 후보 뽑기

    if (candidate == previousWorker) { // 2. 연속 근무 체크
        val nextWorker = weekdayQueue.poll() // 다음 사람 뽑기
        weekdayQueue.addFirst(candidate)     // 원래 후보는 다시 넣어두기 (순서 교체)
        candidate = nextWorker               // 후보 변경
    }
    
    day.worker = candidate
    previousWorker = candidate
    weekdayQueue.addLast(candidate) // 3. 로테이션
}

3. 결과 비교

  • Time Complexity: 기존 O(N^2) 이상의 불확실한 로직에서, O(N) (날짜 수만큼만 순회)으로 명확해졌습니다.
  • Clean Code: `while` 루프가 사라졌고, 들여쓰기는 1단계로 줄어들어 코드가 훨씬 깔끔해졌습니다.

마무리

 

알고리즘 문제를 풀 때 "일단 구현"하는 것도 중요하지만, "적절한 자료구조(Queue)를 쓰면 로직 자체가 단순해진다"는 것을 배울 수 있었습니다. 복잡한 조건문으로 덕지덕지 기운 코드가 있다면, 데이터의 흐름 자체를 바꿀 수 있는지 고민해보세요.