CS3172 > Mats > Assig.#4 > algorithms
Below are three algorithms to help you: (1) Zeller's Algorithm (for computing the day of the week) with a (2) note about computing modulus division for negative values, and (3) an algorithm to determine if a given year is a leap year.
Let
then
weekday = ((13 × month − 1) ÷ 5 + year ÷ 4 + century ÷ 4 + day + year − 2 × century) % 7
variable | value |
---|---|
day | 14 |
month | 3 |
year | 2 |
century | 20 |
((13 × month − 1) ÷ 5
+ year ÷ 4
+ century ÷ 4
+ day
+ year
− 2 × century) % 7
= ((13 × 3 −
1) ÷ 5
+ 2 ÷ 4
+ 20 ÷ 4
+ 14
+ 2 − (2 × 20)) % 7
= (7 + 0 + 5 + 14 + −38) % 7
= −12 % 7 [see below for details on negative n]
= 2
So, 14 May 2002 was a Tuesday.
An easily programmed solution to compute the modulo division of a
negative n by a positive base is
to repeatedly increment n by
base until an equivalent non-negative value for
n is found. In pseudo-code the appropriate algorithm
is while(n<0)
{n ← n+base}
Since the number of times through the loop will be ⌈|n| / base⌉, so we can do the computation faster by applying the following
n % base ≡ (n + (base × ⌈|n| / base⌉)) % base
In MathML notation that looks like:
−12 % 7 | ≡ | (−12 + | (7 × | ⌈|−12|/7⌉)) | % 7 |
≡ | (−12 + | (7 × | ⌈12/7⌉)) | % 7 | |
≡ | (−12 + | (7 × | ⌈1 + 5/7⌉)) | % 7 | |
≡ | (−12 + | (7 × | 2)) | % 7 | |
≡ | (−12 + | 14) | % 7 | ||
≡ | 2 | % 7 | |||
−12 % 7 | ≡ | 2 |
In a leap year, February has 29 days; Otherwise it has 28
days.
A year is a leap year if it is divisible by 4 but not by 100, except
that years divisble by 400 are leap years.
(full citation
below). Pseudo-code based on the C code by K&R is
function isleap(Y : CardinalNumber) : Boolean { [Y = 100×century + year] assert(Y > 0); if (0 = (Y % 400)) then { isleap ← true; } else { if ((0 = (Y % 4)) and (not (0 = (Y % 100)))) then { isleap ← true; } else { isleap ← false; } } }
1900, 1984, and 2000 were leap years. 1899, 1977, and 2001 were not leap years.
To check our accuracy we can use the Unix cal (1) program:
Unix% which cal /usr/bin/cal Unix% cal 2 1900 February 1900 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Unix% cal 2 1984 February 1984 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Unix% cal 2 2000 February 2000 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Unix% cal 2 1899 February 1899 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Unix% cal 2 1977 February 1977 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Unix% cal 2 2001 February 2001 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Unix%