Algorithm/푼 문제

프로그래머스/Lv1/2016년

안개바다 2023. 3. 24. 16:24

문제 설명

 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일같은 날짜는 주어지지 않습니다)

입출력 예

abresult
a b return
5 24 "TUE"

처음 문제를 보고 2가지 단계로 결과를 내기로 결정했다. 

1단계) 기준 일까지의 모든 날짜를 계산한다.

2단계) 7로 나눈 나머지로 요일을 결정한다.

월마다 총 날짜가 다르기 때문에 월별 날짜 데이터가 담긴 배열을 선언하고 그때 그때 배열을 참조해서 문제를 풀기로 결정했다.

function solution(a, b) {
    let month = [{1 : 31},{2 : 29},{3 : 31},{4 : 30},{5 : 31},{6 : 30},
                {7 : 31},{8 : 31},{9 : 30},{10 : 31},{11 : 30},{12 : 31}]
    let week = ['FRI','SAT','SUN','MON','TUE','WED','THU']
    // 이전 달 까지의 모든 일 수 + 1월 1일의 하루 빼기 + 이번달 일 수 b
    let totalDate = b - 1 + month.slice(0,a-1).reduce(
    (acc, cur) => acc + Number(Object.values(cur)), 0);
    return week[totalDate%7]
}

그렇게 해서 1월 1일을 총 몇일 이 지났는지를 계산하고 7로 나누어 나온 나머지를 기준으로 추가로 선언해둔 요일 배열을 참고해서 

알맞은 요일을 return 하도록 설계했다.

리스트와 딕셔너리를 합치 구조(배열안에 객체 구조)를 데이터로 활용하는 방식을 복습할 수 있어 좋은 문제였다.

 

풀이를 제출하고 다른 분들 풀이를 보던 중 내장 메소드를 활용한 풀이들을 보고 리팩토링을 해보았다.

function solution(a, b) {
    let week = ['SUN','MON','TUE','WED','THU','FRI','SAT']
    let day = new Date(`2016-${a}-${b}`).getDay();
    return week[day]
}

Date() 객체를 활용한 풀이이다. new Date('2016-02-01' )를 선언하면 'Mon Feb 01 2016 00:00:00 GMT+0900 (한국 표준시)'

라는 날짜 객체가 생성된다. 여기서 요일값만 추출하고 싶다면 .getDay()를 선언해주면 1이 .getMonth()를 입력해주어도 1일 출력된다.

각각의 의미는 객체의 요일을 출력한것이다.

'SUN':0, 'MON':1, 'TUE':2, 'WED':3, 'THU':4, 'FRI':5, 'SAT':6

이렇게 getDay()는 해당하는 요일에 맞는 숫자를 return한다.

getMonth() 도 마찬가지로 1월은 0으로 12월은 11로 return 한다.

연산시간은 두 방법 다 동일헸기에 이런 방법도 있다는 정도로 이해하면 될 것 같다.

Date() 메소드도 사용법이 단순하지는 않아서 원하는 값으로 출력하게 하기위해서는 부가적인 코드가 많이 필요해서

다른 메소드와 다르게 만능이라는 생각이 들지는 않는다.