[Lv1] 프로그래머스 레벨 1 문제 풀이

이말감·2022년 8월 16일
0

Programmers

목록 보기
30/32

프로그래머스 레벨 1 문제 풀이 - javascript

Math 사용

정수 제곱근 판별

문제

링크

풀이

function solution(n) {
    return Math.sqrt(n) % 1 ? -1 : (Math.sqrt(n) + 1)**2;
}

제곱근을 가진 수인지 판별하는 문제다.

  1. Math.sqrt를 이용해서 제곱근을 구한다.
    1-1. 이때 제곱근이 정수가 아닐 경우, 1로 나눈 나머지가 0이 아니다.
  2. 제곱근이 정수가 아닐 경우 -1을 출력하고, 정수일 경우 (제곱근 + 1)의 제곱을 구한다.

소수 찾기

문제

링크

풀이

function check(num) {
    for (let j = 2; j < Math.round(Math.sqrt(num)) + 1; j++) {
        if (num % j === 0) return false;
    }
    return true;
}

function solution(n) {
    let answer = 0;
    for (let i = 2; i < n+1; i++) {
        if (check(i)) answer += 1;
    }
    return answer;
}

1부터 n 사이의 소수의 개수를 구하는 문제다.

소수는 1과 자기 자신으로만 나누어지는 수이기 때문에 1과 해당 숫자 사이의 어떠한 수로 나눠질 경우 소수가 아니다.

소수를 구하는 방법에 대해 알아보자.
소수를 구하기 가장 간단한 방법은 하나씩 다 나눠보는 것이다.
하지만 시간이 오래 걸리기 때문에 좋지 않은 방법이다.
그렇다면 어떤 방법으로 풀어야 할까???

먼저 특정 수의 약수를 생각해보자.
25의 약수는 1, 5, 25이다.

1 x 25 = 25
5 x 5 = 25
25 x 1 = 25

약수가 대칭으로 짝을 이룬다는 것을 알 수 있다!

또 다른 예를 들어보기 위해 16의 약수를 알아보자.

1 x 16 = 16
2 x 8 = 16
4 x 4 = 16
8 x 2 = 16
16 x 1 = 16

25와 마찬가지로 4 x 4 = 16를 기준으로 대칭적인 모습을 확인할 수 있다.
그러므로 숫자의 제곱근을 기준으로 작은 숫자들로 나눴을 때, 나눠지는지 여부를 확인하면 소수인지 소수가 아닌지 확인할 수 있다.

  1. Math.sqrt로 숫자의 제곱근을 구한다.
    1-1. 제곱근이 정수가 아닐 수도 있으므로 Math.round를 이용해 반올림한 값 구한다.
    1-2. 제곱근의 값도 포함하기 위해 반복문의 범위를 2부터 Math.round(Math.sqrt(num)) + 1까지로 설정한다.
  2. 숫자가 나눠지면 소수가 아니므로 false, 나눠지지 않을 경우 소수이므로 true를 반환한다.
참고

가운데 글자 가져오기

문제

링크

풀이

function solution(s) {
    const number = Math.floor(s.length/2);
    return s.length % 2 ? s[number] : s.slice(number-1, number+1);
}

단어 s의 가운데 글자를 반환하는 문제다.
s의 길이가 짝수일 경우 두 글자, 홀수일 경우 한 글자를 반환하면 된다.

  1. 글자의 길이를 2로 나눈 값을 먼저 구한다. (number)
    1-1. 홀수의 경우 나머지가 있으므로 Math.floor로 버린다.
  2. 글자의 길이가 2로 나눈 값이 0이 아니면 (홀수라는 뜻) number를 인덱스로 한 값을 출력하고, 0일 경우 (짝수라는 뜻) slice로 배열을 분할한다.
    2-1. slice(시작 인덱스[, 끝 인덱스])

나머지가 1이 되는 수 찾기

문제

링크

풀이

function solution(n) {
    for (let i = 2; i < Math.ceil(Math.sqrt(n-1) + 1); i++) {
        if ((n-1) % i == 0) return i;
    }
    return n-1;
}

자연수 n을 나눈 나머지가 1이 되도록 하는 작은 자연수 x를 출력하는 문제다.

이 문제는 위에 있는 소수 찾기 문제 풀이를 이용하면 된다.
나머지가 1이 되려면 n-1을 나눠 떨어지게 하는 수를 구하면 된다.
약수는 대칭을 이루기 때문에 수의 제곱근보다 같거나 작은 수까지 2부터 돌려보면 된다.

  1. Math.sqrt를 이용하여 n-1의 제곱근을 구하고, Math.ceil로 올림해준다.
    1-1. 제곱근도 포함해야 하므로 반복문의 범위를 2부터 제곱근 + 1까지로 설정한다.
  2. 반복문을 돌리면서 n-1이 i로 나눠질 경우, i가 가장 작은 자연수 x가 되므로 반환한다.
  3. 나눠지지 않을 경우 n-1이 가장 작은 자연수 x가 된다.

최소직사각형

문제

링크

풀이

function solution(sizes) {
    let max_size = 0;
    let min_size = 0;
    
    for (let arr of sizes) {
        max_size = max_size > Math.max(...arr) ? max_size : Math.max(...arr);
        min_size = min_size > Math.min(...arr) ? min_size : Math.min(...arr);
    }
    return max_size * min_size;
}

sizes에 저장된 모든 명함을 수납할 수 있는 가장 작은 지갑의 크기를 출력하는 문제다.
문제에서 명함을 돌릴 수 있다고 했으므로 가로, 세로 중 큰 수를 max_size, 작은 수를 min_size에 넣었다.

  1. 반복문을 돌려 명함의 가로, 세로 중 큰 수를 max_size, 작은 수를 min_size에 넣는다.
    1-1. Math.max, Math.min을 이용해서 배열 내 큰 수와 작은 수를 구한다.
    1-1-1. Math.max, Math.min을 사용할 때 스프레드 연산자를 이용해야 한다.
  2. 삼항 연산자를 이용해서 현재 max_size, min_size와 비교하여 더 크거나 작은 수로 할당한다.
  3. 반복문이 끝나고 max_size, min_size값을 곱하여 크기를 구한다.

그 외

시저 암호

문제

링크

풀이

function solution(s, n) {
    let answer = s.split('');
    for (let i in answer) {
        // 빈칸인 경우
        if (answer[i] === ' ') continue;
        let num = answer[i].charCodeAt();
        let tempNum = num + n;
        if (num >= 65 && num <= 90 && tempNum > 90 || 
           num >= 97 && num <= 122 && tempNum > 122) {
           tempNum -= 26;
        }
        answer[i] = String.fromCharCode(tempNum)
    }
    return answer.join('');
}

주어진 알파벳을 n만큼 밀어 새로운 값을 구하는 문제다.
이 문제는 아스키 코드를 사용하여 풀면 된다.

  1. 스프레드 연산자를 이용해 문자열 s를 배열로 바꿔준다.
  2. 반복문을 돌려 원소 하나씩 비교한다.
    2-1. 빈칸일 경우 continue
    2-2. charCodeAt를 이용해 원소의 아스키 코드를 구한다.
    2-3. 아스키 코드에 n을 더한다.
    2-4. 현재 아스키 코드가 소문자인지 대문자인지 확인하고, 각각의 경우에 따라 'z', 'Z'의 아스키코드보다 클 때 26을 빼준다.(아스키코드 'z' - 'a', 'Z' - 'A' 값이 26이다.
    2-5. 변환이 끝났을 경우, String.fromCharCode를 이용해 문자로 변환한다.
  3. join으로 배열을 합친 후 반환한다.

수박수박수박수박수박수?

문제

링크

풀이

function solution(n) {
    return '수박'.repeat(n/2 + 1).slice(0, n);
}

길이 n만큼 수박수박수박수박수박수... 를 반복하여 출력하는 문제다.

  1. repeat을 이용해 반복한다.
    1-1. 이때 반복 횟수는 n / 2 + 1 이다.
    1-1-1. n까지 반복할 필요는 없고, '수박'의 길이가 2이므로 2로 나눈 수 + 1만큼만 반복하면 된다.
    1-2. slice로 n개를 잘라 반환한다.
    1-2-1. slice(시작 인덱스[, 끝 인덱스 + 1])

서울에서 김서방 찾기

문제

링크

풀이

function solution(seoul) {
    return `김서방은 ${seoul.indexOf('Kim')}에 있다`;
}

'kim'의 인덱스 값을 구하는 문제다.
이 문제는 'kim'이 배열에 한 번만 나타나며, 반드시 포함된다는 조건이 있기 때문에 쉽게 풀 수 있다.

indexOf를 사용하면 구하는 문자(숫자)의 가장 앞 인덱스 값을 알 수 있다.
만약 배열에 그 문자(숫자)가 없을 경우 -1을 반환한다.


문자열 다루기 기본

문제

링크

풀이

function solution(s) {
    if (s.length === 4 || s.length === 6) {
        if (s.indexOf('e') > -1 ) return false;
        return +s || +s === 0 ? true : false;
    }
    return false;
}

문자열 s가 숫자로만 이루어졌는지, 아닌지 구하는 문제다.

  1. 문자열 s의 길이가 4 혹은 6인지 확인한다.
  2. s에 'e'가 있는지 확인하고, 있는 경우 false를 반환한다.
    2-1. '10e~'는 숫자이기 때문에 true가 반환되는 문제가 있기 때문이다.
  3. s앞에 +를 붙여 숫자인지 확인한다.
    3-1. +s === 0 조건을 넣어준 이유는 0이면 false가 반환되기 때문이다.
profile
전 척척학사지만 말하는 감자에요

0개의 댓글