본문 바로가기
코테연습

56. 폰켓몬 Javascript

by hxunz 2022. 5. 31.

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

 

코딩테스트 연습 - 폰켓몬

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.

programmers.co.kr

 

 

1. 문제에 대한 이해

  • 우리가 풀어야 할 문제는 무엇인가?
     - 최대한 다양한 종류의 폰켓몬을 가져갈 수 있는 폰켓몬의 종류 몇가지 일까?
  • 주어진 자료는 무엇인가?
     - nums = N마리 폰켓몬의 종류 번호가 담긴 배열
  • 조건은 무엇인가?
     - 같은 종류의 폰켓몬을 데려갈 수 있다.
     - nums의 길이는 항상 짝수이다
     - 가장 많은 종류의 폰켓몬을 선택하는 방법이 여러 가지인 경우에도 선택할 수 있는 폰켓몬 종류 개수의 최댓값 하나만 return
 

2. 계획

  • 전에 비슷한 문제를 알고 있는가?
     - 경우의 수를 구하는 문제라면 위장 문제랑 소수구하기 문제를 참고할 수 있을것같다.
     - 그런데 종류만 알면 되니까 굳이 경우의 수를 다 구해볼 필요가 없을 것 같다.
  • 이 문제를 푸는데 있어서 유용하게 쓸 수 있는 지식은 무엇인가?
     - 배열에서 중복을 제거 할 수 있는 set / filter / includes를 사용할 수 있을것이다.
  • 만약 문제를 풀 수 없다면 문제를 더 단순하게 하기 위해서 주어진 조건을 버려보아라
     - 박사님의 폰켓몬이 2마리일때부터 생각해보자
 
 
  1. 총 데려갈 수 있는 포켓몬의 수를 따로 변수에 할당한다.
  2. 포켓몬이 2마리일때 계산
  3. 4마리일때 계산
  4. 6마리일때 계산해보자  이때 확인해보니까 데려갈 수 있는 포켓몬을 그냥 리턴해줘도 일부 테스크가 통과한다.

  5. 근데 6마리일때 포켓몬이 만약에 6마리인데 종류가 두마리뿐일때 데려갈 수 있는 최대 종류의 수는 2이다..

  6. nums에서 중복값을 제거해보자

  7. [3,3,1,1,2,2,2,2]인 경우 nums.length는 8이고 takePoket은 4 중복제거하면 [3,1,2]길이는 3
  8. 데려갈 수 있는 takePoket이 4마린데 종류는 3개니까 최대로 데려갈 수 있는 종류는 3
  9. [3,1,2,3]인 경우 nums.length는 4이고 takePoket은 2 중복제거하면 [3,1,2]길이는 3
  10. 데려갈 수 있는 takePoket이 2마린데 종류는 3개니까 최대로 데려갈 수 있는 종류는 2

  11. takePoket의 길이 > nums중복제거한배열 => nums중복제거한배열의 길이 리턴
  12. takePoket의 길이 < nums중복제거한배열 => nums중복제거한배열의 길이 리턴

 

 

3. 실행

  • 풀이 계획을 실행하고, 각 단계가 올바른지 점검하라.
const solution = (nums) => {
  const takePoket = nums.length / 2;

  const overlap = [...new Set(nums)];
  const newNums = [...overlap];

  return (takePoket > newNums.length) ? newNums.length : takePoket;
};



test('포켓몬이 두마리일때', () => {
  expect(solution([3, 1])).toEqual(1);
});

test('포켓몬이 네마리인데 각각 다 다른종류일때', () => {
  expect(solution([3, 1, 2, 4])).toEqual(2);
});

test('포켓몬6마리', () => {
  expect(solution([3,3,3,2,2,4])).toEqual(3);
});

test('포켓몬6마리인데 종류2개', () => {
  expect(solution([3,3,3,2,2,2])).toEqual(2);
});

   test('포켓몬8마리', () => {
  expect(solution([3,3,1,1,2,2,2,2])).toEqual(3);
});

 

 

 

const secondSolution = (nums) => {
  const takePoket = nums.length;
  const overlap = nums.filter((it, index) => {
    if (nums.indexOf(it) === index) {
      return it;
    };
  });

  return overlap.length > takePoket ? takePoket : overlap.length;
};

 

 

 

 

어떻게 풀 수 있을까 고민했었는데 
계획 단계에서 조건을 버리라는 부분을 이행해봤다.
폰켓몬의 수를 점점 늘려가면서 반복적인 부분을 발견했고 (가져갈 수 있는 폰켓몬의 개수를 리턴하는 부분)
이 부분을 코드로 작성했더니 테스트 코드가 통과가 됐다.

그런데 에러나는 다른 테스트 코드를 발견했고
왜 에러났을까 생각하고 노트에도 써보고,, 하다가 갑자기 중복제거가 생각났다..!
그래서 중복 제거하고 어떤 상황에서
가져갈 수 있는 폰켓몬의 개수를 리턴할지
아니면 중복제거한 배열의 길이를 리턴할지를 고민해보았고
코드로 작성하고 프로그래머스에 바로 제출했는데 한번에 통과가 됐다

한번에 통과된 적은 처음이라 좋았다.
오랜만에 쉬운 문제를 푸니까 코테 푸는게 더 재밌어졌다. 
앞으로 점점 어려운 문제를 풀 수 있도록 꾸준히 풀어야겠다.

 

'코테연습' 카테고리의 다른 글

58. 실패율 Javascript  (0) 2022.06.08
57. 부족한 금액 계산하기 Javascript  (0) 2022.06.08
55. 체육복 Javascript  (0) 2022.05.31
54. 모의고사 Javascript  (0) 2022.05.29
53. 문자열압축 Javascript  (0) 2022.05.27

댓글