JavaScript - 프로그래머스 레벨 : 1(11) - ORDER BY '정답률'

먹보·2023년 1월 16일
0

1. 폰켓몬

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

홍 박사님 연구실의 폰켓몬은 종류에 따라 번호를 붙여 구분합니다. 따라서 같은 종류의 폰켓몬은 같은 번호를 가지고 있습니다. 예를 들어 연구실에 총 4마리의 폰켓몬이 있고, 각 폰켓몬의 종류 번호가 [3번, 1번, 2번, 3번]이라면 이는 3번 폰켓몬 두 마리, 1번 폰켓몬 한 마리, 2번 폰켓몬 한 마리가 있음을 나타냅니다. 이때, 4마리의 폰켓몬 중 2마리를 고르는 방법은 다음과 같이 6가지가 있습니다.

  • 첫 번째(3번), 두 번째(1번) 폰켓몬을 선택
  • 첫 번째(3번), 세 번째(2번) 폰켓몬을 선택
  • 첫 번째(3번), 네 번째(3번) 폰켓몬을 선택
  • 두 번째(1번), 세 번째(2번) 폰켓몬을 선택
  • 두 번째(1번), 네 번째(3번) 폰켓몬을 선택
  • 세 번째(2번), 네 번째(3번) 폰켓몬을 선택

이때, 첫 번째(3번) 폰켓몬과 네 번째(3번) 폰켓몬을 선택하는 방법은 한 종류(3번 폰켓몬 두 마리)의 폰켓몬만 가질 수 있지만, 다른 방법들은 모두 두 종류의 폰켓몬을 가질 수 있습니다. 따라서 위 예시에서 가질 수 있는 폰켓몬 종류 수의 최댓값은 2가 됩니다.

당신은 최대한 다양한 종류의 폰켓몬을 가지길 원하기 때문에, 최대한 많은 종류의 폰켓몬을 포함해서 N/2마리를 선택하려 합니다. N마리 폰켓몬의 종류 번호가 담긴 배열 nums가 매개변수로 주어질 때, N/2마리의 폰켓몬을 선택하는 방법 중, 가장 많은 종류의 폰켓몬을 선택하는 방법을 찾아, 그때의 폰켓몬 종류 번호의 개수를 return 하도록 solution 함수를 완성해주세요.

function solution(nums) {
    const unique = new Set(nums);
    const newNums = Array.from(unique);
    const N = nums.length
    const n = newNums.length
    return N/2 > n ? n : N/2
}
//
function solution(nums) {
    const unique = new Set(nums);
    const N = nums.length
    const n = unique.size 
    return N/2 > n ? n : N/2
}

🗒️코멘트 : 문제의 길이에 겁을 지레 먹고 위기감을 느꼈지만 생각보다 문제는 간단했다.
어차피 폰켓몬 종류의 개수는 연구실에 있는 폰켓몬 총 수(N)의 절반이기 때문에 만약 폰켓몬 종류(Set으로 중복 제거 후 : n)가 그 수를 넘는다면 당연히 얻을 수 있는 최댓값은 N/2이고 그 수를 못 넘는 다면 n 이기에 단순하게 생각했더니 그게 맞았다.

지난 번 코테 문제를 풀었을 때 Set을 활용하여 문제를 풀었던 터라 One Way만 생각해서 Set으로 바꾼 후 Array로 다시 변경하여 Array의 Length를 구해..길이를 비교했는데 MDN 사이트를 들어가 Set의 속성을 보다보니 Set.size 속성이 있다는 것을 깨닫고 그것을 활용해서 다시 풀었다.

2. 콜라 문제

문제 : 오래전 유행했던 콜라 문제가 있습니다. 콜라 문제의 지문은 다음과 같습니다.

정답은 아무에게도 말하지 마세요.
콜라 빈 병 2개를 가져다주면 콜라 1병을 주는 마트가 있다. 빈 병 20개를 가져다주면 몇 병을 받을 수 있는가?
단, 보유 중인 빈 병이 2개 미만이면, 콜라를 받을 수 없다.

문제를 풀던 상빈이는 콜라 문제의 완벽한 해답을 찾았습니다. 상빈이가 푼 방법은 아래 그림과 같습니다. 우선 콜라 빈 병 20병을 가져가서 10병을 받습니다. 받은 10병을 모두 마신 뒤, 가져가서 5병을 받습니다. 5병 중 4병을 모두 마신 뒤 가져가서 2병을 받고, 또 2병을 모두 마신 뒤 가져가서 1병을 받습니다. 받은 1병과 5병을 받았을 때 남은 1병을 모두 마신 뒤 가져가면 1병을 또 받을 수 있습니다. 이 경우 상빈이는 총 10 + 5 + 2 + 1 + 1 = 19병의 콜라를 받을 수 있습니다.

문제를 열심히 풀던 상빈이는 일반화된 콜라 문제를 생각했습니다. 이 문제는 빈 병 a개를 가져다주면 콜라 b병을 주는 마트가 있을 때, 빈 병 n개를 가져다주면 몇 병을 받을 수 있는지 계산하는 문제입니다. 기존 콜라 문제와 마찬가지로, 보유 중인 빈 병이 a개 미만이면, 추가적으로 빈 병을 받을 순 없습니다. 상빈이는 열심히 고심했지만, 일반화된 콜라 문제의 답을 찾을 수 없었습니다. 상빈이를 도와, 일반화된 콜라 문제를 해결하는 프로그램을 만들어 주세요.

콜라를 받기 위해 마트에 주어야 하는 병 수 a, 빈 병 a개를 가져다 주면 마트가 주는 콜라 병 수 b, 상빈이가 가지고 있는 빈 병의 개수 n이 매개변수로 주어집니다. 상빈이가 받을 수 있는 콜라의 병 수를 return 하도록 solution 함수를 작성해주세요.

function solution(a, b, n) {
    let answer = 0;
  
    while (n>=a){
        answer += parseInt(n/a)*b
        n = parseInt(n/a)*b + n%a
    }
    return answer;
}

🗒️코멘트 : 레벨 0에서 풀었던 치킨 쿠폰하고 똑같은 문제인데....왜 또?

3. 소수 찾기

문제 : 1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.

소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.
(1은 소수가 아닙니다.)

function solution(n) {
  let count = 0;
  for (let i = 2; i <= n; i++) {
      if(isPrime(i) == true){
          count++
      }
  }
  return count;
}

function isPrime(n) {
  if (n <= 3) return true;
  if (n % 2 === 0 || n % 3 === 0) return false;

  for (let i = 5; i * i <= n; i += 6) {
    if (n % i === 0 || n % (i + 2) === 0) return false;
  }
  return true;
}

🗒️코멘트 : 처음 solution 함수 내에서 이중 for 문을 돌려서 문제를 풀었으나...시간초과가 나서 이중 for 문을 조금 더 풀어 하나의 함수를 더 만들어 문제를 풀었는데 시간초과가 풀려 이렇게 진행했다.

시간 효율성...시간 복잡성..제대로 공부를 해야 하는데..혼자서 하기에는 쉽지 않다..

profile
🍖먹은 만큼 성장하는 개발자👩‍💻

0개의 댓글