[프로그래머스] 2016년

지은·2023년 3월 23일
0

Algorithm

목록 보기
18/33

문제

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

제한 조건

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

입출력 예

abresult
524"TUE"

나의 풀이

먼저 요일 배열 days를 만들었고, 1월 1일이 금요일이라 했으므로,
days[1] = "FRI"로 맞추기 위해 목요일부터 시작하도록 했다.

그리고 월별 마지막일을 모아둔 배열 months를 만들었고,
months[1] = 31로 인덱스를 맞추기 위해 0번째 값은 null을 할당해주었다.

현재 월을 나타내는 month 변수를 선언해 1을 할당했다.
현재 월(month)가 a보다 작을 동안 아래의 반복문을 반복한다.

  1. 현재 월의 마지막 날짜(e.g. 1월 31일)의 요일("SUN")을 구한다.
  2. 2월 1일이 "MON"이 되도록 days 배열을 재정렬해준다.
    이때 slice 메소드와 전개 연산자를 사용했다.
  3. 그리고 구하고자했던 월(e.g. 5월)이 되면 반복문에 들어가지 않고, days 배열을 이용해 26일에 해당하는 요일을 반환한다.
function solution(a, b) {
    let days = ['THU', 'FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED'];
    const months = [null, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    let month = 1;

    while(month < a) {
        const idx = months[month] % 7;
        days = [...days.slice(idx), ...days.slice(0, idx)];
        month++;
    }
    
    return days[b % 7];
}

다른 사람의 풀이 1

Date 생성자 함수로 푼 풀이, slice로 요일 부분만 잘라서 반환했다.
새롭게 배운 사실은 두 번째 매개변수로 월이 아니라 월 index를 줘야 한다는거..

function getDayName(a,b){
    var tempDate = new Date(2016, a-1, b); // Tue May 24 2016 00:00:00 GMT+0900 (한국 표준시)

    return tempDate.toString().slice(0,3).toUpperCase();
}

다른 사람의 풀이 2

a가 2보다 작다면, daySumb - 1이다. (index로 접근해야 하므로 -1)

  1. daySum 을 7로 나누어 요일리스트에서 해당 인덱스에 있는 요일을 반환한다.
    e.g. dayList[23 % 7] = "SUN"

a가 2보다 크거나 같다면,

  1. daySum은 월별 마지막일을 모아둔 배열을 0부터 해당 월 앞까지 자른다.
    e.g. a = 5, b = 24라면, daySum = [31, 29, 31, 30]
  2. 그러고나서 reduce를 이용해 모두 더해준다.
    daySum = 121
  3. 마지막으로 b - 1을 더해준다. (마찬가지로 index로 접근해야 하므로 -1)
    121 + 24 - 1 = 144
  4. daySum을 7로 나누어 요일 리스트에서 해당 인덱스에 있는 요일을 반환한다.
    144 % 7 = 4 ("TUE")
function getDayName(a,b){
  var dayList = ['FRI','SAT','SUN','MON','TUE','WED','THU'];
  var monthArr = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  var daySum;
  if(a < 2) {
    daySum = b - 1;
  } else {
    daySum = monthArr.slice(0, a - 1).reduce((a, b) => a + b) + b - 1;
  }
    return dayList[daySum % 7];
}

나는 월씩 끊어서 해야한다고 생각했는데.. 생각해보니 일수를 모두 합쳐서 계산해도 요일을 구할 수 있었다.


다른 사람의 풀이 3

Date 객체에 템플릿 리터럴을 사용해서 날짜를 전달하고 getDay() 메소드를 사용했다.
getDay() 메소드는 일요일을 0, 토요일을 6 이렇게 index로 리턴하기 때문에 요일을 저장한 배열을 이용해서 문자열을 리턴해줬다.

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

오늘의 교훈 : 날짜 관련 알고리즘 문제를 풀 때는 Date 객체와 메소드를 활용하자..🙂

profile
블로그 이전 -> https://janechun.tistory.com

6개의 댓글

comment-user-thumbnail
2023년 3월 23일

너무 어려운거같아요 ,, ㅠㅠㅠ

답글 달기
comment-user-thumbnail
2023년 3월 25일

예전에 스터디할 때 풀었던 문제인데 다시 보니 또 모르겠네요 ㅋ.ㅋ

답글 달기
comment-user-thumbnail
2023년 3월 26일

엄청 헷갈리네여 ..

답글 달기
comment-user-thumbnail
2023년 3월 26일

딱 보고 Date 선언자 밖에 생각 안났는데 다양한 풀이가 있네요! 특히 월 별의 일일 노가다는 보고 놀랐읍니다

답글 달기
comment-user-thumbnail
2023년 3월 26일

Date 선언자 없이 풀라는 곳은 설마 없겠죠 ㅋㅋ

답글 달기
comment-user-thumbnail
2023년 3월 26일

다른 사람의 풀이까지 속시원하게 보고 갑니다!

답글 달기