[프로그래머스] 1. 2016년(Lv1), 2. 멀리뛰기(Lv2), 3. H-Index(Lv2)

손규성·2022년 10월 7일
0

alogrithm

목록 보기
4/22
post-thumbnail

Lv. 1: 2016년✍️


문제 설명

  • 2016년 1월 1일은 금요일이다
  • ab가 매개변수로 주어졌을 때 2016년 ab일의 요일을 리턴하는 함수 작성
  • 리턴 값은 SUN, MON, TUE, WED, THU, FRI, SAT 중 하나로 출력

제한사항

  • 2016년은 윤년이다
  • 2016년 ab일은 실제 있는 날이며, 13월 26일이나 2월 45일 같은 날짜는 주어지지 않습니다

접근 방식

이 문제를 보자마자 자바스크립트의 Date 클래스를 사용하면 쉽게 풀 수 있을 것 같다는 생각이 들었다. 특히 DatetoString() 메서드를 같이 사용하면 날짜를 문자열 형태로, 그것도 문자열 가장 앞에 요일을 표시해서 반환해준다는 사실을 얼마 전에 배웠다.

나의 답안

function solution(a, b) {
    return new Date(2016, a - 1, b).toString().slice(0, 3).toUpperCase();
}
  • Date 클래스를 사용할 때 월(month)은 Index값이기 때문에 입력된 a에서 1을 빼고 입력한다
  • toString() 메서드 이용 후 slice()를 통해 가장 앞 요일 부분만 잘라낸다
  • 문제에서 대문자를 요구하기 때문에 마지막에 toUpperCase()를 사용한다

다른 사람 풀이

function solution(a, b) {
    const week = ['SUN','MON','TUE','WED','THU','FRI','SAT'];
    const leapYear = [31,29,31,30,31,30,31,31,30,31,30,31]; 
    
  	let day = b + 4;
    for(let i = 0; i < a - 1; ++i){
        day += leapYear[i];
    }
  
    return week[day % 7];
}
  • Date 클래스를 사용하지 않고 직접 월 ~ 일요일, 윤년 월별 일수를 배열에 담아 탐색한 방법이다
  • for-loop 전에 day값에 4를 더해준 것은 문제에서 1월 1일이 금요일이라 했기 때문이다
  • 문제 읽자마자 Date클래스와 각종 메서드를 떠올린 나와 다르게 직접 로직을 구현한 것 같아서 매력적이게 느껴졌다


Lv. 2: 멀리 뛰기✍️


문제 설명

  • 효진이는 한번에 1칸 또는 2칸을 뛸 수 있다
  • 칸이 총 4개 있을 때 효진이는 →
    (1칸, 1칸, 1칸, 1칸)
    (1칸, 2칸, 1칸)
    (1칸, 1칸, 2칸)
    (2칸, 1칸, 1칸)
    (2칸, 2칸)
    의 5가지 방법으로 맨 끝 칸에 도달할 수 있다
  • 칸수 n이 매개변수로 주어질 때 효진이가 끝에 도달하는 방법이 몇 가지인지 알아내고, 여기에 1234567을 나눈 나머지를 리턴하는 함수 작성

제한사항

  • 1n2,000

접근 방식

문제 자체는 어렵지 않아 보였지만 처음에는 어떻게 접근해야 할지 감을 잡지 못했다. 하지만 분명 숫자들 간의 패턴이 있을 것 같았다. 그래서 무작정 공책에 직접 숫자 하나하나 적어가며 n이 1 부터 10일 때 각 몇 가지 방법이 존재하는지 노가다 계산해보았다. 이때까지만 해도 분명 n값과 이에 들어갈 수 있는 2의 개수에 따른 패턴이 보일 것 같았다. 이렇게 초점을 잘못 맞춘 덕분에 생각보다 푸는데 오래 걸렸다.

결국 n값이 1씩 증가할 때마다 리턴되는 결과값을 공책 한 쪽에 나열해놓고 나서야 피보나치 수 문제라는 점을 파악했다. f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 4, f(5) = 8

나의 답안

function solution(n) {
    let initialArr = [1, 2];
    
    if(n < 2) return initialArr[n - 1];
    else {
        for(let i = 2; i <= n; i++) {
            initialArr.push((initialArr[i - 1] + initialArr[i - 2]) % 1234567);
        }
    }

    return initialArr[n - 1];
}
  • 1, 2가 들어있는 배열을 만들어주고 n이 2 이하일 때는 n - 1인덱스에 위치한 값 반환
  • n이 2 이상일 때는 for-loop을 돌면서 i - 1(전) + i - 2(전전)을 더한다
  • 배열에 push하기 전 바로바로 % 1234567을 해줘야 배열에 올바른 숫자가 넣어진다
    마지막에만 % 1234567을 해주게 되면 배열에 틀린 값이 입력되어 오답처리 된다

다른 사람 풀이

function solution(n) {
    var answer = 0;
    var dp=[];
    dp[1]=1;
    dp[2]=2;
    for(var i=3;i<=n;i++){
        dp[i]=dp[i-1]+dp[i-2] %1234567;
    }
    answer=dp[n];
    return answer%1234567;
}
  • 아직 공부해보지 않은 dynamic programming을 사용한 풀이가 많이 보여서 흥미로웠고, 개념이 궁금해져서 여러 온라인 글들을 읽어보니 재밌어 보인다
  • 아주아주 짧은 1줄 요약: Overlapping subproblem이 많은 경우 사용한다 (피보나치 수열이 대표적 예시)


Lv. 2: H-Index✍️


문제 설명

  • H-Index는 과학자의 생산성과 영향력을 나타내는 지표이다
  • 어떤 과학자가 발표한 논문n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 H-Index이다
  • 모 과학자가 발표한 논문들의 인용 횟구가 담긴 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index값을 리턴하는 함수 작성

제한사항

  • 과학자가 발표한 논문 횟수는 1편 이상 1,000편 이하
  • 논문별 인용 횟수는 0회 이상 10,000회 이하

접근 방식

처음에는 인용 횟수 중 최댓값을 max로 선언하고,

  • 0 ~ max까지 도는 for-loop을 통해 h 업데이트
  • 두번째 for-loop을 통해 각 citation 탐색하며 h보다 크거나 같을 때 count++
  • 두번째 for-loop 후 count값과 h값이 같고, 현재 hIndex값 보다 크면 hIndex 업데이트

해주면 되는 아주 심플한 문제라고 착각했다.

오답 코드 ❌

function solution(citations) {
    let count = 0,
        hIndex = 0,
        max = Math.max(...citations);

    for(let i = 0; i <= max; i++) {
        let h = i;

        for(let j = 0; j < citations.length; j++) {
            if(citations[j] >= h) count++;
        }

        if(count === h && h > hIndex) hIndex = h;
        count = 0;
    }

    return hIndex;
}

접근 방식에 적어둔 로직 그대로 코드를 작성했다. 이때만 해도 이게 당연히 답이라고 생각해서 코드실행도 안눌러보고 바로 제출했는데 계속 11번 테스트만 실패했다.

여러번 디버깅 해보려고 노력했는데 감이 잘 안잡혔다. 내가 문제를 잘못 이해하고 있다는 생각이 들었다. 그래서 문제에 링크되어 있는 위키백과 링크 포함 H-Index에 대해 몇 개의 온라인 글을 참고했다. 특히 영어로 된 글들이 문제점을 파악하는 데 많은 도움이 많이 되었다.

나의 답안

function solution(citations) {
    let hIndex = 0;

    citations.sort((a,b) => b-a);

    for(let i = 0; i < citations.length; i++) {
        if(i < citations[i]) hIndex++;
    }
    return hIndex;
}

이 로직 그대로 코드를 구현하니 11번 테스트까지 통과할 수 있었다.

profile
블로그 이사 → https://sqsung.tistory.com/

0개의 댓글