저장을 습관화

프로그래머스 LV.0 피자 나눠 먹기 (2) 본문

코딩 테스트/프로그래머스 - 자바스크립트

프로그래머스 LV.0 피자 나눠 먹기 (2)

ctrs 2023. 6. 11. 15:11

프로그래머스 LV.0 피자 나눠 먹기 (2)

https://school.programmers.co.kr/learn/courses/30/lessons/120815

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 문제 명

피자 나눠 먹기 (2)


2. 문제 설명

머쓱이네 피자가게는 피자를 여섯 조각으로 잘라 줍니다. 피자를 나눠먹을 사람의 수 n이 매개변수로 주어질 때, n명이 주문한 피자를 남기지 않고 모두 같은 수의 피자 조각을 먹어야 한다면 최소 몇 판을 시켜야 하는지를 return 하도록 solution 함수를 완성해보세요.


3. 제한 사항

1 ≤ n ≤ 100


4. 예시

n result
6 1
10 5
4 2


5. 기본 제공 코드

afunction solution(n) {
    var answer = 0;
    return answer;
}


6. 제출한 내 답

function solution(n) {
  var answer = 0;
  let lcm = 1; 
  
  while (true) {
    if (lcm % n === 0 && lcm % 6 === 0) {
      break;
    }
    lcm++;
  }
  return lcm / 6;
}

 

6-2. VSC에 작성한 내용

function solution(n) {
  var answer = 0;
  let lcm = 1; //최소공배수

  // 피자의 조각 개수는 6이니
  // 필요한 피자의 판수를 구하기 위해 n과 6의 최소공배수에서 6을 나눈다.
  while (true) {
    if (lcm % n === 0 && lcm % 6 === 0) {
      break;
    }
    lcm++;
  }
  return lcm / 6;
}

// test
console.log(solution(1), "정답 1"); // 1
console.log(solution(2), "정답 1"); // 1
console.log(solution(3), "정답 1"); // 1
console.log(solution(4), "정답 2"); // 2
console.log(solution(5), "정답 5"); // 1
console.log(solution(6), "정답 1"); // 1
console.log(solution(10), "정답 1"); // 5
console.log(solution(100), "정답 50"); // 50
console.log(solution(99), "정답 33"); // 33
console.log(solution(98), "정답 49"); // 49
console.log(solution(97), "정답 97"); // 97
console.log(solution(96), "정답 16"); // 16
console.log(solution(95), "정답 95"); // 95


7. 특이사항

 

고민했던 내용

 

7-1. 사람(n) 곱하기 피자 조각(6)하면 되는가? -> 아님

2명일 경우 1판으로 인당 3조각 먹을 수 있고

3명일 경우 1판으로 인당 2조각 먹을 수 있음

4명일 경우 2판으로 인당 3조각 먹을 수 있고

5명일 경우 5판으로 인당 6조각씩 먹어야 하지만

다시 6명일 경우 1판으로 인당 1조각씩 먹을 수 있음

 

 

7-2. 사람(n)과 판수의 규칙성이 있지 않을까? -> 모르겠음.. 있나..?

사람 피자
1 1x
2 1x
3 1x
4 2x
5 5x
6 1x

각 조건의 x가 일치하지 않음

 

 

7-3. 판수(x)*조각(6)에서 사람(n)을 나눈 값이 0으로 떨어지면 되는가? -> 안됨

1명 1/6x => x/6 => x = 6
2명 2/6x => 2x/6 => x =3

입출력 예시와 맞지 않음

 

 

7-4. 반복문을 사용할까?
피자 조각은 6이니 변수 i는 1부터 시작하여 6i / n = 0이면 i의 값을 리턴한다.

 

틀렸다. 6i / n = 0이 아니라 6i % n = 0이었다. 아직도 나누기와 나머지를 헷갈리네

function solution(n) {
  var answer = 0;
    for (i = 1; i < n; i++) {
      if ((6 * i) % n === 0) {
        return (answer = i);
      }
    }
    return answer;
}

틀렸다.

 

 

7-5. 사람이 1명일 경우를 생각하지 못했다.

n이 1이면 반복문에 들어가자마자 false로 떨어져 answer가 0이 될 것이다.

if else로 나누어 n이 1일 경우를 추가한다.

사람이 0명일 경우 피자가 필요하지 않으니 answer도 0이 된다.

function solution(n) {
  var answer = 0;

  if (n === 1) {
    return (answer = 1);
  } else {
    for (i = 1; i < n; i++) {
      if ((6 * i) % n === 0) {
        return (answer = i);
      }
    }
    return answer;
  }
}

// 어떻게 풀 것인가?
// 피자 조각 나누기 사람(n)이 0으로 만들고 싶다.
// 반복문을 사용할까?
// 피자 조각은 6이니
// 변수 i는 1부터 시작하여
// 6i / n = 0이면 i의 값을 리턴한다.

// 틀렸다. 6i / n = 0이 아니라
// 6i % n = 0이었다. 아직도 나누기와 나머지를 헷갈리네

// 틀렸다.
// 사람이 1명일 경우를 생각하지 못했다.
// n이 1면 반복문에서 거짓으로 떨어져 answer가 0이 된다.
// if else로 나누어 n이 1일 경우룰 추가한다.

// 6i % n이 0이 나오지 않을 경우
//

// test
console.log(solution(1)); // 1
console.log(solution(6)); // 1
console.log(solution(10)); // 5
console.log(solution(4)); // 2
console.log(solution(100)); // 50
console.log(solution(99)); // 33
console.log(solution(98)); // 49
console.log(solution(97)); // 0
console.log(solution(96)); // 16
console.log(solution(95)); // 0
console.log(solution(94)); // 47
console.log(solution(93)); // 31
console.log(solution(92)); // 46
console.log(solution(91)); // 0
console.log(solution(90)); // 15

입출력 예시 6, 10, 4는 통과했으나 채점에서 틀렸다.

어디가 잘못됐지?

 

작은 수에서는 이상없이 잘 작동했으나

큰 수에서는 answer가 0이 나오는 것처럼 무언가 문제가 발생하는 것 같다.

 

 

7-6. 코드를 다 밀고 다시 시작했다

 

사람 수와 필요한 피자 조각의 개수가 최소공배수의 관계를 가진다는 것을 알아냈다.

function solution(n) {
  var answer = 0;
  let cdg = 0;

  // a와 b의 최소공배수는 a와 b의 곱을 a와 b의 최대공약수를 나눈 것과 같다.
  // 순서 1. n이 1인 경우를 제외한다.
  if (n === 1) {
    return (answer = 1);
  } else {
    // 순서 2. n과 6(피자의 조각)의 최대공약수를 구한다.
    for (i = 2; i <= 6; i++) {
      if (n % i === 0 && 6 % i === 0) {
        // 순서 3. 최소공배수를 구하기 위해
        // n과 6를 곱한 값에서 cdg(최대공약수를) 나누고,
        // 필요한 피자의 판 수를 구하기 위해
        // 피자 한 판당 조각의 개수는 6이므로
        // 두 수의 최소공배수에서 다시 6을 나눈다.
        answer = (n * 6) / i / 6;
      } else {
        // 추가. n과 6의 최대공약수가 없을때
        // n과 6을 곱합 값이 두 수의 최소공배수가 된다
        // 하지만, 현재 계산식에서 우리는 피자의 총 판수를 구하고 싶고
        // 피자 한 판당 조각의 개수는 6이므로 n*6/6에서 *6/6은 생략되어
        // 최대 공약수가 없을때 필요한 피자의 판수는 n 자체가 된다.
        answer = n;
      }
    }

    return answer;
  }
}

// test
console.log(solution(1)); // 1
console.log(solution(6)); // 1
console.log(solution(10)); // 10
console.log(solution(4)); // 4
console.log(solution(100)); // 100
console.log(solution(99)); // 99
console.log(solution(98)); // 98
console.log(solution(97)); // 97
console.log(solution(96)); // 16
console.log(solution(95)); // 95
console.log(solution(94)); // 94
console.log(solution(93)); // 93
console.log(solution(92)); // 92
console.log(solution(91)); // 91
console.log(solution(90)); // 15

최소공배수를 구하기 위해 n과 6의 최대공약수를 구한 후,

n*6에서 최대공약수를 나누는 방법을 사용하였다.

 

하지만 제대로 작동하지 않았다.

n과 6의 최대공약수가 없을 경우에는 이상이 없었다.

 

7-7. while문 적용

두 수의 곱에서 최대공약수를 나눠 최소공배수를 구하는 방법이 잘 되지않아

while문을 이용한 최소공배수 구하는 방법을 구글링했다.

적용하니 바로 해결되었다.

function getLCM(num1, num2) {
	let lcm = 1;
   
    while(true){
      if((lcm % num1 == 0) && (lcm % num2 == 0)){
        break;
      }
      lcm++;
    }
  	return lcm
}

스스로의 힘으로 풀어보고 싶어서 3시간 정도 쏟아부었는데 

구글링 한번으로 해결되니 화 나고 답답하고 분하다.

 


8. 다른 사람이 작성한 답

8-1. 굳이 최소공배수를 위한 변수 lcm을 만들 필요가 없었다..

6의 배수에서 n을 나눴을때 나머지가 0인 값으로 시작한다.

const solution = (n) => {
    let piece = 6

    while(true) {
        if (piece % n === 0) {
            break
        }
        piece += 6
    }

    return piece / 6
}

 

8-2.

function solution(n) {
    let pizza = 1;
    while (pizza * 6 % n) {
        pizza++;
    }
    return pizza;
}

 

코딩테스트 그만하고 책이나 다시 읽어야할까