Author:
- Name: Jens Schweikhardt
Location: DE - Federal Republic of Germany (Germany)
To build:
make all
To use:
./schweikh1
Try:
To find the day that Easter falls on in the current year and to show all Easter dates from 1582 to 2199:
./try.sh
Judges’ remarks:
Look at the source. There is something very odd going on here. Where does the real code come from if everything is a C pre-processor statement?
Clearly this is either the Best Use or the Worst Abuse of the C Preprocessor that the judges have seen this year!
Author’s remarks:
What this program does
This program is an implementation of an algorithm that calculates the date of the Sunday following the first full moon after the spring equinox. (Also known as “Easter”, defined this way by the Nicaean Concilium in 325 Anno Domini.) The algorithm is attributed to the famous mathematician Carl Friedrich Gauss [“Meyers Handbuch ueber das Weltall” ‘Handbook About Space’, Meyer, 5th Edition, 1973, p149] and is suitable for anni domini within the Gregorian Calendar, that is, from ad 1582 to ad 2199:
Let
J
be the year.
IfJ
is from1582
to1699
, letM
be22
andN
be2
.
IfJ
is from1700
to1799
, letM
be23
andN
be3
.
IfJ
is from1800
to1899
, letM
be23
andN
be4
.
IfJ
is from1900
to2099
, letM
be24
, letN
be5
.
IfJ
is from2100
to2199
, letM
be24
, letN
be6
.
Leta
be the modulus ofJ
divided by19
.
Letb
be the modulus ofJ
divided by4
.
Letc
be the modulus ofJ
divided by7
.
Letd
be the modulus of(19a + M)
divided by30
.
Lete
be the modulus of(2b + 4c + 6d + N)
divided by7
.
The interesting Sunday is either (only one of them is a valid date):
March
22 + d + e
; or
Aprild + e - 9
with the following exceptions:
April 26 must always be changed to April 19.
April 25 must be changed to April 18 ifd
is28
anda
is greater than10
.
Example:
J = 1962, M = 24, N = 5
a = J % 19 == 5
b = J % 4 == 2
c = J % 7 == 2
d = 119 % 30 == 29
e = 191 % 7 == 2
March 53 is invalid, so the result is April 22 1962.
Why I think this is obfuscated
Apart from the calculation of the Easter date, the definition and
calculation of which are obfuscations in their own right,
obfuscation lurks in many places. Look at those macro identifiers.
What can be more obvious than a program that explicitly mentions the
grammatical constructs it is composed of? If you look at K&RII A.9.3
you will find that a compound statement consists of an opening brace
followed by a declaration list followed by a semicolon followed by a
statement list followed by another semicolon and a closing brace.
Nobody can learn that by heart so I gently remind the reader by
defining a macro that expresses this clearly (line 25). This goes up
to the definition of a translation unit. Unfortunately, due to the
IOCCC’s size restrictions, I had to abbreviate some syntactic
elements. ae
actually reads “assignment expression”. I had to stop
at some arbitrary point, so don’t waste your time trying to find out
how preprocessing tokens form type qualifier lists, cast expressions
or direct abstract declarators. Assuming the reader knows about
these easy to remember language elements is justified in my opinion.
The moral:
Try to be as precise as can be and no one will comprehend what you mean.
The formula:
comprehension = 1/(2**precision)
The interpretation:
“Say nothing and everybody will understand.”
The -I/usr/include
in the build file is needed by gcc on Solaris because
gcc
’s “fixed” header in gcc-lib/sparc-sun-solaris2.5/2.7.2/include/errno.h
is broken (sort of) because it has two identical extern declarations of errno
.
This leads to an error due to the redefinition of main
. The -I
option makes
sure the working /usr/include/errno.h
is found first, which shouldn’t cause any
problems on other systems.
Usage:
The program is run without arguments. It prints all dates in order.
Inventory for 1996/schweikh1
Primary files
- schweikh1.c - entry source code
- Makefile - entry Makefile
- schweikh1.orig.c - original source code
- errno.h - declare errno as an extern int
- try.sh - script to try entry
Secondary files
- 1996_schweikh1.tar.bz2 - download entry tarball
- README.md - markdown source for this web page
- .entry.json - entry summary and manifest in JSON
- .gitignore - list of files that should not be committed under git
- .path - directory path from top level directory
- index.html - this web page