2016년

문제 📖

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

나의 풀이 🙋‍♀️

function solution(a, b) {
  const dayOfTheWeek = ["FRI", "SAT", "SUN", "MON", "TUE", "WED", "THU"];
  const daysOfMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  let sum = 0;

  if (a === 1) {
    sum = b;
  } else {
    for (let i = 0; i <= a - 2; i++) {
      // 1
      sum += daysOfMonth[i];
      if (i == a - 2) {
        sum += b; //2
      }
    }
  }

  const index = sum - Math.floor(sum / 7) * 7; // 3

  return index === 0 ? dayOfTheWeek[6] : dayOfTheWeek[index - 1];
}

내가 생각한 풀이의 순서는 다음과 같다.

  1. 주어진 월(a)전의 총 날짜를 더한 값을 구한다.. = sum
  2. sumb를 더해 필요한 날짜를 모두 더한 값을 구한다.
  3. sum에 7의 배수를 뺐을 때 나올 수 있는 한자리 수를 구해 dayOfTheWeek의 인덱스로 활용한다.

trouble shooting 1 💥

처음 코드

for (let i = 0; i <= a - 2; i++) {
  sum += daysOfMonth[i];
  if (i == a - 2) {
    sum += b;
  }
}

수정한 코드

if (a === 1) {
  sum = b;
} else {
  for (let i = 0; i <= a - 2; i++) {
    sum += daysOfMonth[i];
    if (i == a - 2) {
      sum += b; //2
    }
  }
}

이 부분은 왜 통과하지 못했는지 머리를 굴리다 1월인 경우, 2월인 경우 값을 대입해서 생각해보니 문제점을 찾을 수 있었다.

만약 1월이라면 a는 1이되는데 for문의 조건에 처음부터 충족되지 못해서 sum에 값이 들어가지 않았던 것이다.

if문으로 조건을 달아주긴 했지만 조건문속 반복문속 조건문.. 정말 맘에 들지 않는다..

trouble shooting 2 💥

처음 코드

return dayOfTheWeek[index - 1];

수정한 코드

return index === 0 ? dayOfTheWeek[6] : dayOfTheWeek[index - 1];

계산대로 하면 모든 케이스가 통과해야하는데 13개의 케이스 중 2개가 통과하지 못하고 계속 실패로 걸렸다.

테스트 케이스에 날짜를 하나 하나 추가해서 결과를 확인하던 중 이유를 알 수 있었다.

index가 0이 될 수도 있었던것이었다.

예를 들어 5월 5일인 경우, index126 - (18*7) = 0이 되는데 나는 결과값을 dayOfTheWeek[index-1]로만 리턴해서 결과가 undefined가 나왔던 것이다.

return할 때 삼항연산자를 이용해 index가 0이 될 경우의 케이스도 처리해주었다.

Best Practice #1 👍

function getDayName(a, b) {
  var tempDate = new Date(2016, a - 1, b);

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

//아래 코드는 테스트를 위한 코드입니다.
console.log(getDayName(5, 24));

Date가 있는 걸 알긴 했지만 그러면 너무 단순해질것같아서 사용하지 않았다.

그래도 메소드를 사용한걸 보니 훨씬 보기 편하다.

Best Practice #2 👍

function solution(a, b) {
  const monthDay = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  const weekDay = ["THU", "FRI", "SAT", "SUN", "MON", "TUE", "WED"];

  let days = b;
  for (let i = 0; i < a - 1; i++) days += monthDay[i];

  return weekDay[days % 7];
}

코드가 흘러가는 구성이 내가 작성한 코드와 크게 다르지 않다.

하지만 간결함과 가독성이 크게 다르다.

for문의 조건식에서 <=<로 고쳤을뿐인데 if문이 하나 줄었다.

굳이 sum이라는 변수를 새로 만들지 않고 b에 값을 더해주었다.

굳이… Math.floor()를 사용하지 않고도 그냥 %연산자로 나머지값 계산해서 index로 처리해주었다…

만약 다른 사람이 푼 답에 Best Practice가 있다면 배열 내장 함수를 사용했을 것이라고 생각했는데 아니었다.

물론 배열 내장 함수를 사용할 수도 있지만 이 코드가 가독성도 좋고 제일 좋아보였다.

Leave a comment