저장을 습관화
프로그래머스 LV.0 피자 나눠 먹기 (2) 본문
프로그래머스 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;
}
코딩테스트 그만하고 책이나 다시 읽어야할까
'코딩 테스트 > 프로그래머스 - 자바스크립트' 카테고리의 다른 글
프로그래머스 LV.0 나이 출력 (0) | 2023.06.11 |
---|---|
프로그래머스 LV.0 피자 나눠 먹기 (3) (0) | 2023.06.11 |
프로그래머스 LV.0 피자 나눠 먹기 (1) (0) | 2023.06.11 |
프로그래머스 LV.0 배열의 평균값 (0) | 2023.06.09 |
프로그래머스 LV.0 짝수는 싫어요 (0) | 2023.06.08 |