Nomad Engineer

[일일코테 Day8] 2016년 - 프로그래머스(레벨1) 본문

개발/코딩테스트

[일일코테 Day8] 2016년 - 프로그래머스(레벨1)

universehan 2021. 3. 3. 06:19

문제

2016년의 a월 b일이 무슨요일인지를 계산한다.

 

생각해보기

- a월의 1일이 무슨요일인지 기억하고 b % 7로 요일을 계산한다.

- 그냥 내장 함수를 사용한다.

 

내장함수를 이용하기

Javascript 로 풀어보기

- 내장 함수를 초기화 하고, 요일을 얻는 함수를 사용한다.

year - 연도를 나타내는 정숫값. 0부터 99는 1900부터 1999로 처리합니다.
monthIndex - 월을 나타내는 정숫값. 0은 1월을 나타내고 11은 12월을 나타냅니다.
day 일을 나타내는 정숫값. 기본값은 1입니다.

요일을 얻는 방법

getDay() 메서드는 주어진 날짜의 현지 시간 기준 요일을 반환합니다. 0은 일요일을 나타냅니다.
function solution(a, b) {
    const dayFromZero = new Date(2016, a - 1, b).getDay();
    return ['SUN','MON','TUE','WED','THU','FRI','SAT'][dayFromZero];
}

C++로 풀어보기

Python으로 풀어보기

 

계산을 해보기

최종 요일 = (기준 요일 + (a-1월 까지의 일수) + b) % 7 이라는 식으로 계산해 봤다.

코드

function solution(a, b) {
    const datesPerMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    let day = 4;
    for(let m = 0; m < a - 1; ++m) {
        day += datesPerMonth[m];
    }
    day += b;
    return ['SUN','MON','TUE','WED','THU','FRI','SAT'][day % 7];
}

 

날짜를 계산해보기

좀 더 간결하게 할 수 없을까 생각해 봤다. 7월 까지는 홀수월이 31일 이고, 짝수 월은 2월 제외하고 30일이다, 8월 부터는 그 반대. 결국 2일 간격으로 하루씩 더해진다고 볼 수 있고, 이를 구하는 적당한 식을 생각해 봤다. 

1 월 2 월 3 월  4 월 5 월 6 월 7 월 8 얼 9 월 10 월 11 월 12 월
31 29 31 30 31 30 31 31 30 31 30 31
31 60 91 121 152 182 213 244 274 305 235 366
1 -1 2 2 3 3 4 5 5 6 6 7

7월 까지는 1의 자리수 = (m+1) / 2, 8월 부터 1의 자리수 = (m / 2) + 1.

 

최종 날짜 구하기

2015년 12월 31일은 THU였으니 기본적으로 4부터 시작한다. 거기에 직전 월까지 일 수와 현재 날짜를 더하면 최종 현재까지의 일 수가 나온다. 여기에 7로 나눈 나머지 값을 구하면 해당 날짜의 요일을 알 수 있다.

 

a월 b일 까지의 일 수

    = 목요일 + 전달까지의 일 수 + 이번달 날짜

    = 4 + daysOf(a-1) + b

요일은 7로 위의 계산 결과를 7로 나눈 나머지

 

연산 최적화(최적하 하 필요도 없겠지만...)

나누기 연산은 느리니 쉬프트 연산을 사용했고, 곱하기는 전 달 까지 다 더하는게 어차피 곱하기 연산이니. 그냥 사용했다.

function daysUntil(m) {
    if (m == 0) return 0;
    if (m == 1) return 31;
    let daysForMonth;
    if (m < 8) {
        daysForMonth = ((m + 1) >> 1) -1;
    } else { 
        daysForMonth = (m >> 1);
    }
    return Math.floor(daysForMonth + m * 30);
}

function solution(a, b) {
    let days = 4 + daysUntil(a-1) + b;
    return ['SUN','MON','TUE','WED','THU','FRI','SAT'][days % 7];
}

포문을 쓰는게 더 깔끔해 보인다... 이걸 원한게 아니었는데..

반응형