2016년

구해야 하는 것

  • 2016년 a월 b일이 무슨 요일인지 구하라

주어진 자료

  • 2016년 1월 1일은 금요일
  • a = 월, b = 일
  • 요일의 이름은 SUN, MON, TUE, WED, THU, FRI, SAT(일요일부터 토요일까지)

조건

  • 2016년은 윤년이다.
  • a월 b일은 실제로 있는 날이다.

숨겨진 조건이나 자료

  • 윤년이므로 2월은 29일까지 있다.
  • 1, 3, 5, 7, 8, 10, 12월은 31일까지 있고, 4, 6, 9, 11월은 30일까지 있다.

계획

일단 규칙을 먼저 찾아보자
만약 1월 24일의 요일을 구한다고 하면,

  1. 24 % 7 = 3
  2. 3에서 1일을 빼주면 = 2
  3. 1월 1일은 금요일이므로 24일은 2일 뒤인 일요일이다.

만약 1월 28일의 요일을 구한다고 하면,

  1. 28 % 7 = 0
  2. 0에서 1일을 빼주면 = -1
  3. 1월 1일은 금요일이므로 28일은 1일 전인 목요일이다.

만약 2월 15일의 요일을 구한다고 하면,

  1. 2월 15일은 1월 46일이라고 할 수 있다.(31 + 15)
  2. 46 % 7 = 4
  3. 4에서 1일을 빼주면 = 3
  4. 1월 1일은 금요일이므로 2월 15일은 3일 뒤인 월요일이다.

이제 규칙을 찾았으니 계획을 세워보자

  1. 각 달이 몇일까지 있는지를 배열 month에 저장해 놓는다.
  2. 요일을 배열 day에 저장해놓는다. 이때 SUN부터 SAT까지의 순서로 저장한다.
  3. 금요일이 저장돼있는 인덱스인 5를 fridayIndex에 저장해놓는다.(굳이 저장해놓지 않아도 되긴 함)
  4. 배열 month를 이용해서 b에 (a - 1)월까지의 일 수를 모두 더한다.
  5. move에 b % 7을 저장한다.
  6. move를 1 감소시킨다.
  7. day[fridayIndex에 + move]가 구하고 싶은 요일에 해당하는데, 만약 move가 2 이상인 경우에는 day의 인덱스 범위를 벗어나게 된다.
    ex) move가 3일 경우 day[8]이 되어 인덱스 범위를 벗어나는데, 정답은 금요일의 3일 뒤인 월요일(day[1])이 되어야 한다.
    move가 6일 경우 day[10]이 되어 인덱스 범위를 벗어나는데, 정답은 금요일의 6일 뒤인 목요일(day[4])이 되어야 한다.
    이를 통해 move가 2 이상인 경우에는 day[move - 2]가 정답 요일이라는 것을 알 수 있다.
  8. 따라서 move가 2 이상이면 answer에 day[move - 2]를 저장하고, 그렇지 않으면 day[fridayIndex + move]를 저장한 후 answer를 return 한다.

실행

string solution(int a, int b) {
    int month[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    string day[7] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
    int fridayIndex = 5;
    int move;
    string answer = "";
    
    // (a - 1)월까지의 일 수를 모두 더하기
    for(int i = 0; i < a - 1; i++) {
        b += month[i];
    }
    
    // day 배열에서 얼만큼 이동할지 구하기
    move = b % 7;
    move--;
    
    if(move >= 2) { // fridayIndex + move가 day의 인덱스 범위를 벗어날 때
        answer = day[move - 2];
    }
    else {
        answer = day[move + fridayIndex];
    }
    
    return answer;
}

반성

  • 4.까지의 과정 후에 {b + (fridayIndex - 1)} % 7을 하면 인덱스 범위에 대한 별도의 처리 과정 없이 바로 요일의 인덱스를 구할 수 있다.
  • 계획 중 move를 1 감소시키는 과정이 있는데, 사실 명확한 이유가 있는 게 아니라 뭔가 느낌상 1일을 빼줘야 할 것 같았다. 그래서 다른 사람의 풀이를 찾아보니까 1월 1일이 하루가 지난날이 아니기 때문에 빼는 거라고 한다.
    문제 풀 때 모든 계획에 대해서 왜 그래야 하는지를 꼭 짚고 넘어가도록 해야겠다.