프로그래머스 서버 증설 횟수 js

이명진·2025년 5월 22일
0

코드카타

목록 보기
75/76

2025 년도 에 나온 따끈따끈한 문제다

문제 해설

게임 서버를 운영하고 있다고 가정을 한다. 파라미터 는 사람수 , 서버가 증설될때 버틸수 있는사람수 , 서버 유효기간 이 주어진다.
기본적으로 서버가 버틸수 있는 사람수를 넘어서는 사람수가 나올때 서버를 증설 시키고 서버를 증설 시킬때 유효기간 까지 적용시키면서
운영할때 최소로 빌려야 하는 서버의 갯수를 리턴하면 된다

내가 한 문제 접근

최솟값을 리턴 하면 된다 라고 하니 그리디 문제 인줄 알았으나 시간이 한정적으로 하루 만 주어져서 체크 할 시간이 24개 밖에 없다보니
그냥 일일이 순회 하면서 증설 갯수를 세야 겠다 라고 생각했다.

그래서 plusSever를 변수로 삼아서 서버의 개수를 증설해야 하면서 값을 늘리고 줄여가며 이용 가능한 사람수를 체크하려고 했었는데
동시에 여러개의 서버를 빌릴수 있다는 가능성에 배열로 문제를 풀기로 하였다

첫번째 시도

최적화를 위해서 우선 견딜수 있는 사람수가 주어지면 continue로 넘어가고 서버를 증설하는 로직을 넣었다.
말 그대로순서대로 생각한 대로 로직을 만들었다

function solution(players, m, k) {
  var answer = 0;
  let availablePlayer = m;
  let plusSever = [];
  for (let player of players) {
  
    if (availablePlayer > player) {
// 만약 견딜수 있는 사람수 이면 넘어간다 
// 이때 서버를 빌렸다면 시간은 멈추지 않기 때문에 서버를 정리해준다 
      if (plusSever.length > 0) {
        plusSever = plusSever.map((sever) => sever - 1).filter((x) => x > 0);
      }
      availablePlayer = m + m * plusSever.length;
      continue;
    }
// 서버를 빌려야 할 때의 로직 
    if (plusSever.length > 0) {
// 서버가 있다면 서버를 정리해준다 
      plusSever = plusSever.map((sever) => sever - 1).filter((x) => x > 0);
    }
// 부족한 서버갯수구하기 
    let lessSever = player - availablePlayer;
    lessSever = Math.floor(lessSever / m);

    answer += lessSever + 1;
    let getSever = Array.from({ length: lessSever + 1 }).fill(k);
// 서버 증설 
    plusSever = plusSever.concat(getSever);
    availablePlayer = availablePlayer + m * plusSever.length;
  }

  return answer;
}

결과는 테스트 코드는 만점이었지만 제출 하였을때는 많이 틀렸다
뭔가 꼬이는게 많았다
질문하기를 통해서 테스트 코드를 찾게 되어서 적용해봤는데 틀렸다

찾은 테스트 코드

[7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 3, 1

문제를 보니 서버갯수를 마지막에 구하고 마지막에 서버를 증설해주니
다음에 증설되어 견딜수있는 사람수가 정리가 안되었고 위의 테스트 코드에서 두번째 인덱스의 4일 경우에 그냥 코드가 견딜수있다고 판단해
넘어가 버렸다
답이 3인데 내 로직은 2를 리턴했다

순서 잘못이라고 생각하여서

서버 증설을 우선으로 하고 마지막에 서버를 정리해주자 라고 생각하고 문제를 다시 풀었다

두번째 시도

function solution(players, m, k) {
   var answer = 0;
  let availablePlayer = m;
  let plusSever = [];
  for (let player of players) {
  // 서버 증설 
    if (availablePlayer <= player) {
      let lessServer = player - availablePlayer;
      lessServer = Math.floor(lessServer / m) + 1;
      answer += lessServer;
      let getSever = Array.from({ length: lessServer }).fill(k);
      plusSever = plusSever.concat(getSever);
    }
// 서버 정리하기 
    if (plusSever.length > 0) {
      plusSever = plusSever.map((sever) => sever - 1).filter((x) => x > 0);
    }
// 견딜수 있는 사람수 정리 
    availablePlayer = m + m * plusSever.length;
  }

  return answer;
}

로직의 순서만 바꿨을 뿐이었는데 올 통과 올 PASS할수 있었다

로직이란게 순서가 매우 중요하다는 것을 다시한번 깨닫게 되었다

나온지 얼마 안된 문제여서 질문하기를 통해서 테스트 케이스를 모으기 힘들었는데 마침 딱 한개있는 테스트 코드로 문제를 풀수 있었다

굳굳

profile
프론트엔드 개발자 초보에서 고수까지!

0개의 댓글