개발 공부/알고리즘

[항해 99 모의고사 알고리즘] "신대륙 발견" JavaScript / .new Date(), for, while

U_D 2022. 3. 15. 21:22

1. 문제 설명

성륜이는 오늘 항해99를 시작했다. 성격이 급한 성륜이는 항해 1일 차부터 언제 수료를 하게될 지 궁금하다.
항해 1일 차 날짜를 입력하면 98일 이후 항해를 수료하게 되는 날짜를 계산해주는 알고리즘을 만들어보자.

 

 

 

2. 제한 조건

1 ≤ month ≤ 12
1 ≤ day ≤ 31 (2월은 28일로 고정합니다, 즉 윤일은 고려하지 않습니다.)

 

 

 

 

3. 예시

입력/출력

 

 

4. 풀이

[for 활용]

  1. 총 일자수를 만들어 줄 Days 변수 선언
  2. months로 각 달의 일 수를 배열 변수로 저장
  3. for문을 돌리는데 실제 달(month)에서 -1을 해야 배열에서는 순서가 맞기 때문에 i를 month - 1 로 설정
  4. i는 months의 길이만큼 반복
  5. Days에는 결국 months가 반복되는 만큼 더해진다.
    ex. 1월달이면 배열의 0번째 값인 31부터 더해짐
         31 + 28 + 31 ...
  6. 대신 조건은 [시작한 날 (day) + 98일] => 이 값은 우리가 알고자 하는 날짜의 최대치로 i가 반복되는 구간을 정해주는 if문이 된다. 즉, 1월이면 31 + 28 + 31 + 30 = 120이 3번째 index에서 멈추게 된다.
  7. 그럴 경우에 month는 멈춘 자리에서 +1을 해주면 실제 달이 된다. (배열의 index 순서와 실제 달은 1차이가 남)
  8. day는 우리가 알고 싶어하던 day + 98일을 고려하지 않고 1월 1일부터 더한 Days가 되었기 때문에
    6번에서 멈췄던 달의 총 날짜에서 1월 1일 기준으로 계산됐던 총 날짜인 Days에서 실제 날짜에서 98일이 더해진 day + 98일을 빼주면 된다. 1월 18일을 예로 들면 month[i]는 3번째 index에서 멈췄기에 30의 값을 가지고 Days는 위에서 계산된 120일 day는 18일이다. 식으로 바꾸면 day = 30 - (120 - (18 + 98))
  9. 그리고 리턴하면 값이 나온다.
  10. 여기서 문제는 우리가 98이 되기전에 months의 length가 끝나는 순간인다.
    예를들면 11월이 값으로 들어오면 배열의 10번째(30) + 11번째(31)이 더해지는데 98이라는 if문에 충족하지 못하고 for문이 끝나게 된다. 그때 for문 바로 밑에 있는 if문을 충족하지 못하고 밖에있는 if문에 도달하는데 i가 11일 경우에 다시 0의 값을 반환하게 해서 for문이 돌게끔 해준다. 하지만 i = 0으로 보내주게 되면 i++ 때문에 for문에서 증가를 하게 되고 i =1부터 시작되기 때문에 한달이 앞서나가서 더해지는 오류가 생겼다. 그래서 i == 11일때 i = -1로 정의 해줘서 for문에 갔을 때 i = 0으로 시작되게 해야한다.
function solution(month, day) {
  let Days = 0;
  let months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  for (let i = month-1; i <= months.length; i++) {
    Days += months[i];
    if (Days >= day + 98) {
      month = i + 1;
      day = months[i] - (Days - (day + 98))
      return `${month}월 ${day}일`
    }
    if (i == 11) {
      i = -1;
    }
  }
}
console.log(solution(1, 18))

 

[Date 메쏘드 활용]

function solution(month, day){
	let result = new Date(`2021,${month},${day}`)
  result.setDate(result.getDate() + 98)

  month = result.getMonth()
  day = result.getDate()
  
	return result = (month+1) + '월 ' + day + '일'
}
console.log(solution(6,22))

 

 

[while 활용]

function solution(month, day){
  let result=""
  let days = 0
  
  date = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

  month -= 1
  
  while(days + date[month] < 98) {
    days += date[month++]
    month > 11 ? month = 0 : {}
  }

  day += 98-days

  if(date[month] < day)
    day -= date[(month++)]

  result = (month+1) + '월 ' + day + '일'
  
   return result;
}

console.log(solution(1,18))