A hack towards a one line Calendar Program
Ashish Gupta
May 1995
Surprisingly short amount of code can be written for complex decision making programs like a Calendar using integer arithmetic tricks.
For example , a calendar program which takes a date and returns the day has to perform many decisions like
Number of days in the month
Taking care of leap years like 1996 , 2000 and exceptions like 1900
Calculating the days passed on the date since the beginning of the year
etc.
Normally , such a program may take 30-50 lines to write if written using normal programming constructs.
However , using clever manipulation in math. expressions , this calendar program can be written in only one line. I kind of came across the idea when I was playing with integer expressions to perform a complex calculation.
Applications:
This technique of using integer expressions to make complex decisions can be used for many other problems , any problem which requires case by case handling and many conditional statements. I have not yet evaluated any performance related advantages they may offer for doing highly repetitive operations.
Ok, here is the code
Note : Months are passed as 0 for Jan , 1 for Feb ...
Function for returning Numbers of days in a given month and year
int Days(int m,int
y)
{
return
30+(m+m/8)%2+(1-((3*m-6)/(3*m-7))-1/m)*(-1-(3*(y%4))/(3*(y%4)-1)-3*(y%400)/(3*(y%400)-1)+3*(y%100)/(3*(y%100)-1));
}
Function for returning Numbers of days passed sinnce the beginning of the year on a given date,month and year
int Days_Passed(int
m ,int y,int d)
{
return
d+((m+(m%2))/2+(m/8)*(1-(m%2)))*31+(m/2-(m/8)*(1-(m%2)))*30+((3*m-3)/(3*m-4))*(-2+1-(3*(y%4))/(3*(y%4)-1)-3*(y%400)/(3*(y%400)-1)+3*(y%100)/(3*(y%100)-1));
}
Function
for returning the day on a given date,month and year
( Takes care of calendar rules described above ! )
int Day(int m ,int
y,int d)
{
return
(d+((m+(m%2))/2+(m/8)*(1-(m%2)))*31+(m/2-(m/8)*(1-(m%2)))*30+((3*m-3)/(3*m-4))*(-2+1-(3*(y%4))/(3*(y%4)-1)-3*(y%400)/(3*(y%400)-1)+3*(y%100)/(3*(y%100)-1))+(y+((y-1)/4)-(y/100)+(y/400))-1)
% 7;
}
Download C++ code to test these (these might need very slight modification for gcc. Originally written long time back in DOS and Turbo C++ days) :
Explanation : Mail me. I plan to write something up soon.