Programmers: Javascript 문제풀이(9-16번)

너겟·2022년 5월 14일
0
post-thumbnail

Programmers_coding test

프로그래머스에서 자바스크립트 알고리즘을 풀어볼 수 있다!

9번) 핸드폰 번호 가리기

9번 문제 풀러가기!

전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 "*"으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.

조건:

  • phone_number는 길이 4 이상, 20이하인 문자열입니다.

입출력 예:

풀이:
*를 repeat한 다음 substr으로 원하는 부분의 characters를 가져와서 붙인다.

function solution(phone_number) {
    let hide = '*'.repeat(phone_number.length -4);
    let last = phone_number.substr(phone_number.length -4);
    
    let answer = hide + last;
    return answer;
}

note

  • string에서 특정 위치에 있는 character(한개)를 가져오려면 charAt()이라는 함수를 사용하면 된다!

  • substring 사용법
    str.substring(indexStart[, indexEnd])

    여기서 인자값:
    indexStart
    반환문자열의 시작 인덱스
    indexEnd
    옵션. 반환문자열의 마지막 인덱스 (포함하지 않음.)

10번) 행렬의 덧셈:

10번 문제 풀러가기!

행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.

조건:

  • 행렬 arr1, arr2의 행과 열의 길이는 500을 넘지 않습니다.

입출력 예:

풀이:
2차원 배열 너무 어려워서 결국 해결하지 못했다....
해설을 보니, let을 두번 돌리는 것까진 비슷한데 sum이라는 새로운 배열을 선언해주고 push로 배열안에다가 하나씩 넣어주는 개념이었다.

function solution(arr1, arr2) {
   var answer = [];
   
   for(let i=0; i<arr1.length; i++){ //[1,2][2,3]
       let sum = [];
       for(let j=0; j<arr1[i].length; j++){ //arr1 안의 배열의 길이 (2번)
           sum.push(arr1[i][j] + arr2[i][j]) // 1번째 1+3, 2번째 2+4 / 3번째 2+5 4번째 3+6
       }
       answer.push(sum) // [4,6],[7,9]
   }
   return answer;
}

note

  • 2차원 배열 너무 어렵다 ㅠㅠ

11번) x만큼 간격이 있는 n 개의 숫자

11번 문제 풀러가기

함수 solution은 정수 x와 자연수 n을 입력 받아, x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야 합니다. 다음 제한 조건을 보고, 조건을 만족하는 함수, solution을 완성해주세요.

조건:

  • x는 -10000000 이상, 10000000 이하인 정수입니다.
  • n은 1000 이하인 자연수입니다.

입출력 예:

풀이:

  • 10번에서 배열을 새로 선언해주고 그 안에 push하는 반복문 쓴 것을 활용하면 된다.
function solution(x, n) {
    let answer = [];
    for(let i=1;i<=n;i++) {
        answer.push(x * i);
    }
    
    return answer;
}

12번) 부족한 금액 계산하기

12번 문제 풀러가기

놀이기구의 원래 이용료는 price원 인데, 놀이기구를 N 번 째 이용한다면 원래 이용료의 N배를 받기로 하였습니다. 즉, 처음 이용료가 100이었다면 2번째에는 200, 3번째에는 300으로 요금이 인상됩니다.
놀이기구를 count번 타게 되면 현재 자신이 가지고 있는 금액에서 얼마가 모자라는지를 return 하도록 solution 함수를 완성하세요.
단, 금액이 부족하지 않으면 0을 return 하세요.

조건:
놀이기구의 이용료 price : 1 ≤ price ≤ 2,500, price는 자연수
처음 가지고 있던 금액 money : 1 ≤ money ≤ 1,000,000,000, money는 자연수
놀이기구의 이용 횟수 count : 1 ≤ count ≤ 2,500, count는 자연수

입출력 예

입출력 예 설명
이용금액이 3인 놀이기구를 4번 타고 싶은 고객이 현재 가진 금액이 20이라면, 총 필요한 놀이기구의 이용 금액은 30 (= 3+6+9+12) 이 되어 10만큼 부족하므로 10을 return 합니다.

풀이:
먼저 이용료를 계산해야 할텐데, 기존 가격에서 1,2,3,4-- 이렇게 올라갈수록 더해줘야한다. 금방 풀 수 있을거라고 생각했는데 생각보다 조금 시간이 걸렸다.

function solution(price, money, count) {
    let total = 0
    for(let i= 1; i < count+1; i++) {
        total += price * i 
    } 
    if (total>= money) {
        let answer = total - money;
        return answer;
    } else {
        let answer = 0 ;
        return answer;
    }    
}

13번)2016년

13번 문제 풀러가기!

2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터 토요일까지 각각 SUN,MON,TUE,WED,THU,FRI,SAT 입니다. 예를 들어 a=5, b=24라면 5월 24일은 화요일이므로 문자열 "TUE"를 반환하세요.

조건:

  • 2016년은 윤년입니다.
  • 2016년 a월 b일은 실제로 있는 날입니다. (13월 26일이나 2월 45일같은 날짜는 주어지지 않습니다)

입출력 예:

풀이:
윤년이 뭔지 일단 찾아봤다. 윤년의 특징은 1년이 366일 이어서 4로 나눠진다는 사실!
366일 중에 몇번째 날인지 번호를 부여해서 7을 나눈 다음 요일을 배열로 만들어 찾아내려 했지만 간단한 고유함수가 있었다...(시간낭비했다고는 생각하지말자! 어떻게 작동하는지에 대해 생각해볼 시간을 가졌으니!)

function solution(a, b) {
    return new Date(2016,a-1,b).toString().slice(0,3).toUpperCase();   
}

Date 함수를 쓰면 이렇게 나온다:
Mon Aug 30 2021 00:00:00 GMT+0900 (한국 표준시)

여기서
toString() 함수를 통해서 문자열로 변환 시키고,
0번째 부터 글자 3개를 잘라 (slice)
대문자로 변환해서 리턴해서 원하는 결과를 얻을 수 있다.

내가 처음 생각했던 방법으로 원시적으로 푸는 방법은:
한 달에 몇일이 있는지를 쭉 나열하여 지나간 months and days를 계속 더해가는 것

unction solution(a, b) {
    // 윤년은 2월이 29일까지 있고, 1년이 366일이다.
    // 4, 100, 400으로 나누어지는 년도는 윤년이다.
    const weekToDay = ['SUN','MON','TUE','WED','THU','FRI','SAT'];
    const leapYearMonths = [31,29,31,30,31,30,31,31,30,31,30,31]; 
    let day = b+4; // 1월 1일은 FRI, b가 1일 때 인덱스로는 5가 되어야한다.
    // 1월은 이전 월의 일수를 더하지 않음으로 a-1 조건으로 해야한다.
    for(let i = 0; i < a-1; ++i){
        day += leapYearMonths[i];
    }
    return weekToDay[day%7];
}

note
느낀점: 고유함수에 대해 많이 알아놓자! 너무 편하다!!!

14번) 나누어 떨어지는 숫자 배열

14번 문제 풀러가기!

array의 각 element 중 divisor로 나누어 떨어지는 값을 오름차순으로 정렬한 배열을 반환하는 함수, solution을 작성해주세요.
divisor로 나누어 떨어지는 element가 하나도 없다면 배열에 -1을 담아 반환하세요.

조건:

  • arr은 자연수를 담은 배열입니다.
  • 정수 i, j에 대해 i ≠ j 이면 arr[i] ≠ arr[j] 입니다.
  • divisor는 자연수입니다.
  • array는 길이 1 이상인 배열입니다.

풀이:
간단한 문제이지만 다양한 함수가 들어간다. 먼저 새로운 배열을 선언해주고, 기존 배열 내에서 divisor로 나눴을때 나머지가 0이라는 조건을 달아준다.
마지막에 sort 함수를 써서 오름차순으로 정렬을 해줄건데, 여기서 요소를 문자열로 인식하기 때문에 5와 10의 경우 1이 앞에 있는 10이 먼저 나와버리는 현상이 나타난다. 이걸 바로잡아주려면 값을 비교해주는 함수를 써야한다.

  • 여기서 내림차순으로 정렬해주려면 a - b 부분을 b - a로 바꿔주면 된다.
function solution(arr, divisor) {
    var answer = [];
    for (let i=0;i<arr.length;i++) {
        if (arr[i] % divisor === 0) {
            answer.push(arr[i])
        }
    
        if (answer.length === 0) {
            answer.push(-1)
        }
    }    
    answer.sort(function(a,b) {
        return a - b;
    });
    
    return answer;
}

15번) 내적

15번 문제 풀러가기!

길이가 같은 두 1차원 정수 배열 a, b가 매개변수로 주어집니다. a와 b의 내적을 return 하도록 solution 함수를 완성해주세요. 이때, a와 b의 내적은 a[0]b[0] + a[1]b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

입출력 예:

설명:
입출력 예 #1
a와 b의 내적은 1(-3) + 2(-1) + 30 + 42 = 3 입니다.

입출력 예 #2
a와 b의 내적은 (-1)1 + 00 + 1*(-1) = -2 입니다.

풀이:

function solution(a, b) {
   let num = 0;
    for (let i=0; i< a.length; i++) {
       num += a[i]*b[i]
   };
    return num;
}

16번) 문자열 내 p와 y의 개수

16번 문제 풀러가기!

대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다. 예를 들어 s가 "pPoooyY"면 true를 return하고 "Pyy"라면 false를 return합니다.

입출력 예:

풀이:
대문자와 소문자의 구별이 없다고 했기 때문에 비교하기 전에 한쪽으로 다 바꿔주고 시작: .toUpperCase() 함수 사용
아이디어는 split으로 string을 끊어주고 나눠진 string의 갯수를 세어서 -1을 하는 것!

function solution(s){
    let result = ""
    let a = s.toUpperCase().split("P").length -1;
    let b = s.toUpperCase().split("Y").length -1;
    if (a===b) {
        return result = true
    } else {
        return result = false
    }
}

note
다른 사람의 풀이:

return s.toUpperCase().split("P").length === s.toUpperCase().split("Y").length;

이렇게 다른 풀이를 보면... 아 정말 나는 코드에 군더더기가 많구나 라고 느낀다. 같은 기능이고 성능도 비슷할거지만 조금 깔끔하게 예쁘게 보이게 써보고 싶다!

profile
꾸준하게 하는 법을 배우는 중입니다!

0개의 댓글