본문 바로가기

생각하나

요일계산 빨리하기


누군가가 불러준 년월일의 요일을 빨리 계산하는 법을 생각해본다.

요일을 계산하는 데는 일, 월, 년의 정보가 필요하다.


좀 더 나누어서 년도와 월, 일로 나누어 생각을 해보자.


1. 년도 계산
일년은 365일이다.

365 = 7 * 52 + 1

따라서 일년의 차이는 같은 월-일이면 요일에 하루 차이가 난다.

2013년 1월 1일이 화요일이었기 때문에 2014년 1월 1일은 수요일이다.


여기에는 윤년이라는 변수가 숨어있다.

윤년은 366일이므로 2일 차이가 난다.


그레고리력의 정확한 윤년 규칙은 다음과 같다.

  1. 서력 기원 연수가 4로 나누어 떨어지는 해는 윤년으로 한다.(2004년, 2008년, 2012년…)
  2. 이 중에서 100으로 나누어 떨어지는 해는 평년으로 한다.(2100년, 2200년, 2300년…)
  3. 그 중에 400으로 나누어 떨어지는 해는 윤년으로 둔다.(1600년, 2000년, 2400년 …)

http://ko.wikipedia.org/wiki/윤년


따라서 올해 1월 1일을 기준으로 찾아야 하는 년도까지 윤년의 개수를 헤아리면 된다.


윤년의 개수를 헤아리는 방식

윤년의 개수를 헤아리려면 %4 계산을 잘 해야 한다.

두 년도 사이의 윤년을 계산하려면 /4 계산을 한다.

1997년 ~ 2013년 사이의 윤년은 계산해보면 4개의 윤년이 있다.

내림(2013/4) - 올림(1997/4) + 1 = 503 - 500 + 1 = 4


+1을 해주는 것은 차이가 아니라 개수이기 때문이다.


물론 100년 단위의 계산이 있어야 하지만 우선 제끼고 보자.


년도에 따른 요일 차이 = 올해 - 해당년도 + 윤년의 개수



2. 월 계산

일년 12달은 30일로 똑같지 않고 각기 다른 날짜를 가지고 있다.

1월 - 31, 2월 - 28(29), 3월 - 31, 4월 -30, 5월- 31, 6월 - 30,

7월 - 31, 8월 - 31, 9월 - 30, 10월 - 31, 11월 - 30, 12월 - 31


가능하다면 오늘이 올해 몇번째 날인지 알면 좋겠지만,

암산을 잘 한다면 쉬운 덧셈이지만 계산하기 쉽지 않다.

머리 속에 1월 부터 12월까지의 더한 합의 인덱스를 가지고 있다면 좋겠지만,

합이 커서 숫자가 커서 부담이 될법 하다.

따라서 나머지(%, 모듈라) 연산을 통해 간략화하는 방법도 좋다.

나머지를 구하는 밑수는 당연히 7이다.


나머지 : 3, 0, 3, 2,  3,   2,  3,   3,  2,  3,   2,   3 

합         0, 3, 6, 8, 11, 13, 14, 16, 18, 21, 23, 26

나머지:  0, 3, 6,  1,  4,  6,   0,  2,    4,  0,   2,  5


첫번째 1월은 자신을 구하는 것이기 때문에 필요없다.


이 뜻은 2013년 1월 1일이 화요일이니 2월 1일은 +3한 금요일이라는 뜻이다.

윤년이라면 3월부터 1씩 더하면 된다.


3. 일 계산 

2013년 2월 20일 수요일이니 2월 1일을 요일을 계산한다.

2월 1일 요일 = (20-1)%7 = 19 % 7 = 5

수요일보다 5 작은 요일은 수요일보다 2 큰 요일이니 금요일이다.

그럼 1월 1일은 다시 3을 빼면 화요일이다.


4. 지금까지 과정을 합쳐서 계산해보자.

1987년 6월 29일은 무슨 요일일까?

오늘이 2013년 2월 20일 수요일이다.


1). 먼저 1월 1일이 무슨 요일인지 계산한다.

앞에서 한 일 계산을 그대로 이용한다.

우리는 화요일(2) 라는 것을 알아냈다.


2). 년도 값을 구한다.

년도에 따른 요일 차이

= 올해 - 해당년도 + 윤년의 개수

= 2013 - 1987  + 윤년의 개수

= 26 + (503-497+1) = 26+ 7 = 33


33 % 7 = 5


1987년 1월 1일은 화요일보다 -5 뺀 (+2)한 목요일이다.


3). 월값을 구한다.

1987년은 평년이고, 6월 1일은 6월은 4이므로 +4한(-3 한) 월요일이다.

(29 -1) %7 = 28 %7 = 0


1987년 6월 29일은 월요일이다.


이 계산을 반복 숙달해서 연습한다면,

누구나 손쉽게 재빨리 요일을 계산할 수 있다.


또 다른 한 가지 방법은 모든 요일 계산을 0년 1월 1일을 기준으로 할 수도 있다.

0년 1월 1일을 계산해두고,

윤년만 계산하면 간단한 덧셈과 곱셈으로 해결가능하다.


좀더 정교한 수식은 좀 더 생각해봐야겠다.


아님말고

정교한 수식을 생각하려다가 검색을 해보았더니, 역시나 이미 존재한다.

아래 Day of the Week Calculation 주소들을 보면 답이 있다.

오래동안 많은 사람들이 생각해왔던 문제였나 보다.

http://www.merlyn.demon.co.uk/zel-1882.htm

http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

http://en.wikipedia.org/wiki/Zeller's_congruence

Zeller의 방법은 멋지다. 월까지 %7 연산으로 하는 방법을 고안해내다니, 모든 연산이 %4(윤년), %7(요일) 두개로 해결할 수가 있다.

저 공식하나면 만년달력을 함수 하나로 구현해 넣을 수가 있다.