fix Makefile, README.md and .gitignore for 2000/rince

This commit is contained in:
Landon Curt Noll committed 2023-03-15 14:03:34 -07:00
1 parent 568940b9bf
commit 3b44e798c8
3 files changed
+569 -450

No files matched your search

+1
View File
@@ -1 +1,2 @@
dmy2jd
rince
+301 -186
View File
@@ -1,215 +1,330 @@
#!/bin/make
# 2000 makefile
#!/usr/bin/env make
#
# Copyright (C) Simon Cooper, Landon Curt Noll, Peter Seebach
# and Leonid A. Broukhis, 2000.
# All Rights Reserved. Permission for personal, educational or non-profit
# use is granted provided this this copyright and notice are included in its
# entirety and remains unaltered. All other uses must receive prior permission
# from the contest judges.
# IOCCC 2000 winning entry - rince
SHELL= /bin/sh
CAT= cat
RM= rm
SED= sed
TRUE= true
#CINCLUDE= -I ${HOMEBREW_PREFIX}/include/SDL2
# optimization
################################################################################
#
# Most compiles will safely use -O2. Some can use only -O.
# A few compilers have broken optimizers and thus you may
# not want anything.
# Regarding individual entries:
#
# IOCCC winning entry code may not work on your system. Even with standards,
# conditions and build environments change, especially when it comes to more
# extreme code such you might find in an IOCCC winner. Moreover, what was
# allowed and liked in one IOCCC contest may no longer be liked/allowed in
# later IOCCC years.
#
# Corrections on winning author and fixing typos in remarks are VERY WELCOME.
#
# GitHub pull requests are welcome:
#
# If you have a patch that might make running an entry work in modern Unix-like
# environments, please create a GitHub pull request for the IOCCC judges to
# consider.
#
# Suggestions and corrections regarding Makefiles, winning author information,
# fixing typos in remarks, and code patches are welcome via opening a GitHub
# issue or better yet, by creating a GitHub pull request for the IOCCC judges
# to consider. To form a GitHub issue or GitHub pull, please visit:
#
# https://github.com/ioccc-src/winner
#
################################################################################
# This work by Landon Curt Noll and Leonid A. Broukhis is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
#############################
# shell used by this Makefile
#############################
#
SHELL= bash
#######################
# common tool locations
#######################
#
include ../../var.mk
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Common C compiler warnings to silence
#
#CSILENCE=
CSILENCE= -Wno-empty-body -Wno-error -Wno-implicit-function-declaration \
-Wno-incompatible-pointer-types -Wno-parentheses -Wno-return-type \
-Wno-unevaluated-expression
# Common C compiler warning flags
#
#CWARN= ${CSILENCE}
#CWARN= -Wall ${CSILENCE}
#CWARN= -Wall -Wextra ${CSILENCE}
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
# Compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=gnu99
# Compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitness:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# Defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DM_PI=3.14159265358979323846
# Include files that are needed to compile
#
#CINCLUDE=
#CINCLUDE= -include stdlib.h
#CINCLUDE= -include stdio.h
#CINCLUDE= -include stdlib.h -include stdio.h
CINCLUDE= -I ${X11_INCDIR} -I ${X11_INCDIR}/X11
#CINCLUDE= `${SDL2_CONFIG} --cflags`
# Optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
OPT= -O2
#OPT= -O1
#OPT= -O2
OPT= -O3
# flags for ANSI compiles
# Default flags for ANSI C compilation
#
# NOTE: Some ANSI compilers make use of -Xa to turn on ANSI mode,
# others such as gcc may want -ansi, others (Compaq Tru64 Unix)
# want -std1, and others may want nothing at all.
# Adjust the CFLAGS line as needed.
#
# NOTE: Some compilers cannot optimize, or optimize some entries
# incorrectly. You might want to turn on -O to see if your
# compiler can handle them.
#
#
#CFLAGS= -Xa ${OPT}
#CFLAGS= -std1 $(OPT)
CFLAGS= -ansi ${OPT}
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
NO_ANSI_CFLAGS=
#NO_ANSI_CFLAGS=
# Libraries needed to build
#
#LIBS=
#LIBS= -lm
LIBS= -lm -L ${X11_LIBDIR} -lX11
#LIBS= `${SDL2_CONFIG} --libs`
# NOTE: On some systems, the library path does not include the location
# of the X11 libraries. You might need to use a -L/path/to/X11/lib/dir
# in order to compile with these libs.
#
X11CCFLAGS= -I/usr/X11R6/include -I/usr/X11R6/include/X11 -I/usr/include/X11
#X11CCFLAGS=
X11LDFLAGS= -L/usr/X11R6/lib
#X11LDFLAGS=
# Perl
#
PERL= perl
#PERL= perl5
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
#
# Some entries seem to need gcc. If you have gcc, set
# both CC and MAY_NEED_GCC to gcc.
#
# If you do not have gcc, set CC to the name of your ANSI compiler, and
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
# to disable such programs.
# C compiler to use
#
CC= cc
MAY_NEED_GCC= gcc
#CC=clang
#CC=gcc
# winners that compile under ANSI C
# Compiler add-ons or replacements for clang only
#
WINNERS= anderson schneiderwent primenum bellard bmeyer briddlebane dhyang \
dmy2jd jarijyrki dlowe natori rince robison thadgavin tomx
ALT_NAMES= schneiderwent.orig briddlebane.orig thadgavin.orig
DATA_FILES= schneiderwent_files bmeyer_files jarijyrki_files
all: ${WINNERS}
# Best use of flags
ifeq ($(CC),clang)
#
anderson: anderson.c
${CC} ${CFLAGS} $? -o $@
# Most Timely Output
CSILENCE+= -Wno-comma -Wno-float-conversion -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-poison-system-directories \
-Wno-shorten-64-to-32 -Wno-sign-conversion -Wno-strict-prototypes \
-Wno-unreachable-code
#
schneiderwent: schneiderwent.c
${CC} ${CFLAGS} $? -o $@
schneiderwent_files: schneiderwent.data
schneiderwent.orig: schneiderwent.orig.c
${CC} ${CFLAGS} $? -o $@
# Best Abuse of CPP
CWARN+= -Weverything
#
primenum: primenum.c
${CC} ${CFLAGS} $? -o $@
endif
# Most Specific Output
# Specific add-ons or replacements for gcc only
#
bellard: bellard.c
${CC} ${CFLAGS} $? -o $@
ifeq ($(CC),gcc)
#
#CSILENCE+=
#
#CWARN+=
#
endif
# Best Utility
#
# machines operating in 64 bit mode:
#
bmeyer: bmeyer.c
${CC} -DY= -O6 $? -o $@ -lm
#
# linux/x86, glibc 2.0, libc4/5:
#
# bmeyer: bmeyer.c
# ${CC} -DY="__setfpucw(0x127f)" -O6 $? -o $@ -lm
#
# linux/x86, glibc 2.1:
#
# bmeyer: bmeyer.c
# ${MAY_NEED_GCC} -DY='int x=0x127f; __asm__ ("fldcw %0" : : "m" (*&x))' \
# -O6 $? -o $@ -lm
bmeyer_files: lavabus.pgm lenna.glic michael.pgm
# Best Abuse of User
##############################
# Special flags for this entry
##############################
#
briddlebane: briddlebane.c
${CC} ${CFLAGS} $? -o $@ -lm
briddlebane.orig: briddlebane.orig.c
${CC} ${CFLAGS} $? -o $@ -lm
# Best Layout
ENTRY= rince
PROG= ${ENTRY}
#
dhyang: dhyang.c
${CC} ${CFLAGS} $? -o $@
dmy2jd: dmy2jd.c
${CC} ${CFLAGS} $? -o $@
# Best of Show
OBJ= ${PROG}.o
DATA=
TARGET= ${PROG} dmy2jd
#
jarijyrki: jarijyrki.c
${CC} ${X11CCFLAGS} ${CFLAGS} -DNeedFunctionPrototypes \
-DU=40 -DT=98 '-Dz=(T+1)*U*U' -DQ=80 -DS=20 -DN=10 -DB=5 -DG=23 \
-Dp=7 '-DM=((p+1)*Q)+S' '-DH=(G*S)+S+S' -DC=XK_Up -DL=XK_Down \
-DO=XK_Left -DV=XK_Right -DR=XK_Escape -D_=XK_BackSpace \
$? -o $@ ${X11LDFLAGS} -lX11
ALT_OBJ=
ALT_TARGET=
jarijyrki_files: sheet1.info
# Worst Abuse of the Rules
#################
# build the entry
#################
#
# NOTE: You will need to adjust this path to the place where Perl has been
# installed on your system. Running "perl -V" may help you locate
# this place.
#
# The following bit of perl may help determining the values you need:
#
# perl -MConfig -e 'print "$Config{archlibexp}/CORE\n"'
#
#
dlowe: dlowe.c
${CC} ${NO_ANSI_CFLAGS} -DPERL_POLLUTE \
`${PERL} -MExtUtils::Embed -e ccopts` $? -o $@ \
`${PERL} -MExtUtils::Embed -e ldopts`
# Best Small Program
#
natori: natori.c
${CC} ${CFLAGS} $? -o $@ -lm
# Astronomically Obfuscated
#
rince: rince.c
${CC} ${X11CCFLAGS} ${CFLAGS} -DM_PI=3.14159265358979323846 \
$? -o $@ -lm ${X11LDFLAGS} -lX11
# Best game
#
robison: robison.c
${CC} ${CFLAGS} $? -o $@
# Most Portable Output
#
thadgavin: thadgavin.c
${CC} ${CFLAGS} $? -o $@ -lcurses -lm
thadgavin.orig: thadgavin.orig.c
${CC} ${CFLAGS} $? -o $@ -lncurses -lm
# Most Complete Program
#
tomx: tomx.c
${CC} ${CFLAGS} $? -o $@
everything: ${WINNERS} ${ALT_NAMES} ${DATA_FILES}
clean:
${RM} -f *.o a.out core ${WINNERS}
clobber: clean
${RM} -f ${WINNERS}
${RM} -f ${ALT_NAMES}
nuke: clobber
all: data ${TARGET}
@${TRUE}
install: all
${CAT} ${WINNERS} ${ALT_NAMES} > /dev/null
.PHONY: all alt data everything clean clobber install \
love haste waste maker easter_egg sandwich \
supernova deep_magic magic charon pluto
${PROG}: ${PROG}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: data ${ALT_TARGET}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
# both all and alt
#
everything: all alt
###############
# utility rules
###############
#
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
@-if [ -f indent.c ]; then \
echo ${RM} -f indent.c; \
${RM} -f indent.c; \
fi
clobber: clean
${RM} -f ${TARGET} ${ALT_TARGET}
@-if [ -e sandwich ]; then \
${RM} -f sandwich; \
echo 'ate sandwich'; \
fi
install:
@echo "Dr. Spock says that is not logical!"
@${TRUE}
# you may be able to misunderstand the source by reading indent.c
#
indent.c: ${PROG}.c
@if which "${GINDENT}" >/dev/null 2>&1; then \
echo ${RM} -f $@; \
${RM} -f $@; \
echo "${GINDENT} < $< > $@"; \
${GINDENT} < $< > $@; \
elif which "${INDENT}" >/dev/null 2>&1; then \
echo ${RM} -f $@; \
${RM} -f $@; \
echo "${INDENT} < $< > $@"; \
${INDENT} < $< > $@; \
else \
echo "no intent tool found, ident $< yourself, sorry"; \
echo "exit 1"; \
exit 1; \
fi
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
maker:
@echo 'Participate in a maker faire'
@${TRUE}
easter_egg:
@echo "you expected to often misunderstand this $${RANDOM} magic"
@echo "chongo '<was here>' /\\oo/\\"
@echo "Eggy"
sandwich: easter_egg
@if [ `id -u` -eq 0 ]; then \
echo 'Okay.'; \
echo "$${RANDOM}`date +%s`$${RANDOM}" > $@; \
else \
echo 'What? Make it yourself.'; \
exit 1; \
fi
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: sandwich
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v6; \
else \
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
fi
@echo "A $@ helps ${MAKE} the elements that help form planets"
@${TRUE}
deep_magic: supernova
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 7889066cdbdf09b0408021754586e895be641cc9be29e7eafd3ca65359541f17 \
--FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \
else \
echo "Wrong! Do it again!"; \
sleep 2; \
echo "Wrong! Do it again!"; \
sleep 2; \
echo "Wrong! Do it again!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --level 20003 --mode 5717175 --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \
else \
echo "If you don't eat yer meat, you can't have any pudding!"; \
echo "How can you have any pudding if you don't eat yer meat?!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: magic
@echo "$@ is a dwarf planet"
@echo "dwarf is a type of planet"
@echo "therefore IAU, $@ is a planet"
pluto: charon
${MAKE} charon
@echo "$@ is a dwarf planet"
@echo "dwarf is a type of planet"
@echo "therefore, $@ is a planet"
@echo "having lots of planets is good feature because supernovae can help ${MAKE} a lot of them"
+267 -264
View File
@@ -1,333 +1,336 @@
Astronomically Obfuscated:
# Astronomically Obfuscated:
James Bonfield
MRC Laboratory of Molcular Biology
Hills Road,
Cambridge
CB2 2QH
England
James Bonfield
MRC Laboratory of Molcular Biology
Hills Road,
Cambridge
CB2 2QH
England
# To build:
Judges' Comments:
```sh
make
```
To build:
### To run:
make rince
```sh
./rince number number2
```
To run (using an X windows server):
### Try:
./rince
```sh
make dmy2jd
./rince 0.001 `./dmy2jd 7.8 1 1610`
```
Also try:
## Judges' comments:
make dmy2jd
./rince 0.001 `./dmy2jd 7.8 1 1610`
This program may have you going around in circles :-) Try running it
first before reading the Selected Author's Comments below.
The judges verified the correctness of output for recent dates
thru visual observation.
## Author's comments:
### How to use it
The simplest way to run it is with no arguments. Just type:
```sh
./rince
```
You will need to have access to X windows, although it doesn't require
desperately high resolution and there are no known limitations on colour
depth.
The display will change slowly over time, although it may take 10 minutes
or more to be visible. For those that cannot wait that long the program
has a built in time machine. Indeed the program knows the speed of light,
which is used to ensure that we see the "live" pictures. Simply specify
the fraction of a day to skip forward for each screen refresh. I suggest:
```sh
./rince 0.01
```
To display the output (still guessing?) for a given date, specify two
arguments. The first argument is as before and the second argument is a
Julian day number (given as a fractional component). Eg:
```sh
./rince 0 2441193.6
./rince 0.01 2441193.6
```
A Julian day is defined to be the number of days since January 1st in
the year -4712 (4713BC), starting at 12 noon GMT.[1] To aid conversion
from our time (GMT) to Julian day there is a supplementary program
named: dmy2jd.c. Run it with "day_float month year" as arguments. See
below for an example.
### What it does
This program plots the positions of the four Galilean moons of Jupiter,
as seen from earth. It doesn't correct for your location on earth, but I
assure you that the parallax is minimal!
The moons are labelled with roman numerals from I to IV. I being the
closest to the planet and IV being the furthest. They are:
I Io
II Europa
III Ganymede
IV Callisto
Amazingly, all it takes is a pair of binoculars to see the Galilean moons,
so the results can be experimentally checked. (Note that at present, the
best views of Jupiter are over the autumn/winter.)
This program may have you going around in circles :-) Try running it
first before reading the Selected Author's Comments below.
The positions of the moons should be correct for binoculars, but possibly
not if you have a telescope or if you are in the southern hemisphere. In
that case I suggest that to get the correct image you look at the screen
from inside the monitor whilst standing on your head. In case of
confusion, please consult the following chart (*):
The judges verified the correctness of output for recent dates
thru visual observation.
N
^
|
E <---+---> W
|
v
S
(*) Not to scale.
Selected Author's Comments:
### History
How to use it
-------------
Galileo discovered the moons in January 1610.
"http://www-isds.jpl.nasa.gov/cwo/cwo_54ga/html/cd/galileo.htm" states
the following:
The simplest way to run it is with no arguments. Just type:
```
By early 1610, Galileo had further improved his telescope by
double its power, so it now enlarged objects a thousand
times. He began looking at the stars and couldn't believe how
many more he could now see! The number seemed infinite. He was
beginning to realize the fixed stars weren't a flat distant
wall on a globe, but a three-dimensional expanse bigger than
anyone had ever thought!
./rince
Then, on January 7, about an hour after sunset, Jupiter rose
in the east, and Galileo happened to turn his powerful scope
on its bright disk. It wasn't the first time he had looked at
Jupiter, but before it was with one of his lesser-powered
telescopes. This time, though, he noticed three small but
bright stars near the planet, two to one side and one to the
other. He wondered at how bright the small stars were and how
they were arranged in what seemed like a straight line. The
next night he decided to look at Jupiter again, and to his
surprise, the stars had moved. But not in such a way as he
would expect. If Jupiter was moving as it normally should, the
stars would be east of Jupiter. But all three were to the
west! The next night was cloudy, but on January 10, Galileo
was able to observe the planet again. One of the stars was
gone, and the other two were now on the east side. As the
stars moved around Jupiter on each succeeding night, and were
finally joined by a fourth star, it dawned on Galileo that
what he had found were moons orbiting Jupiter! Almost at once
he realized that this was proof that not all objects orbited
the Earth. Here were four bodies that were orbiting
Jupiter. One argument against the sun-centered theory was, if
the Earth orbited the sun, wouldn't the moon get left behind?
Here he could see for himself that somehow, a planet could
orbit the sun, and not leave a moon behind!
```
You will need to have access to X windows, although it doesn't require
desperately high resolution and there are no known limitations on colour
depth.
Thus we can plot Galileo's discoveries using the following three plots:
The display will change slowly over time, although it may take 10 minutes
or more to be visible. For those that cannot wait that long the program
has a built in time machine. Indeed the program knows the speed of light,
which is used to ensure that we see the "live" pictures. Simply specify
the fraction of a day to skip forward for each screen refresh. I suggest:
```sh
./rince 0 `./dmy2jd 7.8 1 1610`
./rince 0 `./dmy2jd 8.8 1 1610`
./rince 0 `./dmy2jd 10.8 1 1610`
```
./rince 0.01
However we can go one better by seeing what Galileo would have seen if it
wasn't cloudy on the 9th. Try "./rince 0 `./dmy2jd 9.85 1 1610`" to see
what he was missing out on. I wonder what he'd have made of that!
To display the output (still guessing?) for a given date, specify two
arguments. The first argument is as before and the second argument is a
Julian day number (given as a fractional component). Eg:
Galileo discovered the fourth moon a few days later.
./rince 0 2441193.6
./rince 0.01 2441193.6
I've tried typing these dates in to two Java based Jovian moon plotters,
but both I tried had problems dealing with dates earlier than 1900. More
professional software, such as the SkyMap program [3] gets these values
correct and this compares well with the above description and with this
IOCCC entry.
A Julian day is defined to be the number of days since January 1st in
the year -4712 (4713BC), starting at 12 noon GMT.[1] To aid conversion
from our time (GMT) to Julian day there is a supplementary program
named: dmy2jd.c. Run it with "day_float month year" as arguments. See
below for an example.
The year 4713BC was chosen by Joseph Justus Scaliger in the 16th Century,
so clearly this program has a long history :-) A more complete description
of the origins of Julian Days can be found at:
What it does
------------
http://aa.usno.navy.mil/AA/faq/docs/millennium.html
This program plots the positions of the four Galilean moons of Jupiter,
as seen from earth. It doesn't correct for your location on earth, but I
assure you that the parallax is minimal!
### Assumptions
The moons are labelled with roman numerals from I to IV. I being the
closest to the planet and IV being the furthest. They are:
1. The ASCII character set is used.
I Io
II Europa
III Ganymede
IV Callisto
2. That an enormous comet hasn't changed the course of Jupiter (or Earth!).
3. That the date has not been specified as the gap between the Julian and Gregorian calendar.
4. That the DISPLAY environment variable is set and the X display can opened. If this is not the case the program will crash.
5. There is a year 2000BC problem :-)
Amazingly, all it takes is a pair of binoculars to see the Galilean moons,
so the results can be experimentally checked. (Note that at present, the
best views of Jupiter are over the autumn/winter.)
More specifically, the plots for dates that far back are too inaccurate
to be of realistic use. Comparisons against SkyMap Pro [3] show that
there is a good similarity (but not much more) up to about 500BC.
The positions of the moons should be correct for binoculars, but possibly
not if you have a telescope or if you are in the southern hemisphere. In
that case I suggest that to get the correct image you look at the screen
from inside the monitor whilst standing on your head. In case of
confusion, please consult the following chart (*):
6. The code definitely is not portable - it will produce incorrect results if run from the surface of Mars.
N
^
|
E <---+---> W
|
v
S
### Obfuscations
(*) Not to scale.
In addition to the normal obfuscations, I feel that the code contains
some less common tricks. Taken through the standard rounds listed in the
guidelines, the code attempts to pass these as follows:
1. Look at the original source
History
-------
With luck, pure casual inspection should not reveal much except
that the program contains the X Windows logo (a big clue) and
contains a date. This date may give a clue to a few people that
this is an astronomical program.
Galileo discovered the moons in January 1610.
"http://www-isds.jpl.nasa.gov/cwo/cwo_54ga/html/cd/galileo.htm" states
the following:
Unfortunately I was stretched for space which meant that the
large string constant could not be split up using a "partA"
"partB" method which clearly limits the code layout. However the
space saved by using a single long string constant is more than
outweighed by ability to further obfuscate.
By early 1610, Galileo had further improved his telescope by
double its power, so it now enlarged objects a thousand
times. He began looking at the stars and couldn't believe how
many more he could now see! The number seemed infinite. He was
beginning to realize the fixed stars weren't a flat distant
wall on a globe, but a three-dimensional expanse bigger than
anyone had ever thought!
2. convert ANSI tri-graphs to ASCII
Then, on January 7, about an hour after sunset, Jupiter rose
in the east, and Galileo happened to turn his powerful scope
on its bright disk. It wasn't the first time he had looked at
Jupiter, but before it was with one of his lesser-powered
telescopes. This time, though, he noticed three small but
bright stars near the planet, two to one side and one to the
other. He wondered at how bright the small stars were and how
they were arranged in what seemed like a straight line. The
next night he decided to look at Jupiter again, and to his
surprise, the stars had moved. But not in such a way as he
would expect. If Jupiter was moving as it normally should, the
stars would be east of Jupiter. But all three were to the
west! The next night was cloudy, but on January 10, Galileo
was able to observe the planet again. One of the stars was
gone, and the other two were now on the east side. As the
stars moved around Jupiter on each succeeding night, and were
finally joined by a fourth star, it dawned on Galileo that
what he had found were moons orbiting Jupiter! Almost at once
he realized that this was proof that not all objects orbited
the Earth. Here were four bodies that were orbiting
Jupiter. One argument against the sun-centered theory was, if
the Earth orbited the sun, wouldn't the moon get left behind?
Here he could see for himself that somehow, a planet could
orbit the sun, and not leave a moon behind!
These are not used.
Thus we can plot Galileo's discoveries using the following three plots:
3. C pre-process the source ignoring #include lines
4. C pre-process the source ignoring #define and #include lines
./rince 0 `./dmy2jd 7.8 1 1610`
./rince 0 `./dmy2jd 8.8 1 1610`
./rince 0 `./dmy2jd 10.8 1 1610`
This does a good job of expanding out the code, but it does not
clarify things greatly. The use of #defines has been restricted
primarily to a space-saving mechanism.
However we can go one better by seeing what Galileo would have seen if it
wasn't cloudy on the 9th. Try "./rince 0 `./dmy2jd 9.85 1 1610`" to see
what he was missing out on. I wonder what he'd have made of that!
Additionally, the use of typedefs means that the types used are
still obscured unless further replacement edits are made.
Galileo discovered the fourth moon a few days later.
5. Run it through a C beautifier.
I've tried typing these dates in to two Java based Jovian moon plotters,
but both I tried had problems dealing with dates earlier than 1900. More
professional software, such as the SkyMap program [3] gets these values
correct and this compares well with the above description and with this
IOCCC entry.
GNU indent seems to do a reasonable job, provided that the
#defines are expanded first. This doesn't lay the algorithm
particularly bare though as most of the obfuscations are not
simple code layouts.
6. Examine the algorithm.
The year 4713BC was chosen by Joseph Justus Scaliger in the 16th Century,
so clearly this program has a long history :-) A more complete description
of the origins of Julian Days can be found at:
The algorithm operates on two levels. The main visible level is
by taking a large string and breaking this down into a series of
op-codes (which I have termed J-code). These are then executed.
http://aa.usno.navy.mil/AA/faq/docs/millennium.html
To get to the real method of how it works, you need to decode
the op-code string (which deliberately contains as many ; { and
} symbols as possible), which will give you a reverse-polish
notation chunk of mathematics.
Sensible people amongst you will simply refer to the referenced
book :-)
Assumptions
-----------
7. Lint it.
1. The ASCII character set is used.
I no longer have lint, although I do have access to Purify. I'm
happy to say that purify does not detect any memory errors or
memory leaks.
2. That an enormous comet hasn't changed the course of Jupiter (or Earth!).
See below for compilation warnings.
3. That the date has not been specified as the gap between the Julian
and Gregorian calendar.
8. Compile it.
4. That the DISPLAY environment variable is set and the X display can
opened. If this is not the case the program will crash.
I'm sorry to say that there are several warnings issued by the
compiler.
5. There is a year 2000BC problem :-)
More specifically, the plots for dates that far back are too inaccurate
to be of realistic use. Comparisons against SkyMap Pro [3] show that
there is a good similarity (but not much more) up to about 500BC.
Firstly, the return type for X() is not specified, so it
defaults to int. Horror of all horrors - this function does not
return an integer type (it doesn't contain any specific
returns). The return value from X() is not accessed. The same
problem occurs in main - it does not return. However main never
exits unless there is a serious error.
6. The code definitely is not portable - it will produce incorrect results
if run from the surface of Mars.
The 6th argument of XDrawText (which should be XTextItem) is
passed as a compatible structure, but without casting. This is
to reduce code space. A more elegant solution is to remove the
"struct {...} Z" completely and use "XTextItem
f={i-127+r/3*2,r%3+r/3+1,0,E}" at the start of XDrawText
block. Although this is accepted by several compilers, it is not
strict ANSI due to the non-constant initialisers. A pity.
Note that I make use of usleep(). This is a POSIX call (it is
BSD), but it supported on many systems. It may be implemented
using select() or poll() if required, or as a final solution you
may change the usleep(10000) to sleep(1). To compile on systems
which do not have usleep, but do have select, the following may
suffice as an additional compiler argument:
Obfuscations
------------
```sh
-Dusleep={time_t v[2]={0,10000};select(0,0,0,0,v);}
```
In addition to the normal obfuscations, I feel that the code contains
some less common tricks. Taken through the standard rounds listed in the
guidelines, the code attempts to pass these as follows:
Gcc complains about "unreachable code at beginning of switch
statement", although removing some of this code will prevent
the algorithm from working.
1. Look at the original source
Gcc also suggests that I should be using extra parenthesis, but
I'm taking this as good comment :-)
With luck, pure casual inspection should not reveal much except
that the program contains the X Windows logo (a big clue) and
contains a date. This date may give a clue to a few people that
this is an astronomical program.
Unfortunately I was stretched for space which meant that the
large string constant could not be split up using a "partA"
"partB" method which clearly limits the code layout. However the
space saved by using a single long string constant is more than
outweighed by ability to further obfuscate.
In addition to the above, the program has the following useful(?)
obfuscations:
2. convert ANSI tri-graphs to ASCII
1. The algorithm requires many floating point numbers (about
50). These are encoded as ASCII.
These are not used.
2. The J-code algorithm has op-codes designed to be space
saving. They are all one byte, but many are also considered as
white-space by the rules. This algorithm forms part of the same
string that the floating point constants are embedded
within. What does the ";" command do in J-code?
3. C pre-process the source ignoring #include lines
4. C pre-process the source ignoring #define and #include lines
3. The J-code language is both stack based and variable based. This
"uncleanliness" is not ideal from a computer science angle, but
when has cleanliness been considered as good in IOCCC? :-)
This does a good job of expanding out the code, but it does not
clarify things greatly. The use of #defines has been restricted
primarily to a space-saving mechanism.
4. Association of unconnected data by implied function usage. Eg
use of strlen() and sizeof() simply to return useful numerical
values, using irrelevant arguments.
Additionally, the use of typedefs means that the types used are
still obscured unless further replacement edits are made.
5. As we already have a dependency on ASCII this has been abused
further. Specifically some integer constants are specified as
ASCII and some ASCII constants are integers. This hides the true
meaning for the values.
5. Run it through a C beautifier.
6. Red herrings: there's a couple of pieces of code whose
appearance is just there to mislead the unfirm of mind.
I've only tried to include such examples in places where at
first glance the code appears to be executed.
GNU indent seems to do a reasonable job, provided that the
#defines are expanded first. This doesn't lay the algorithm
particularly bare though as most of the obfuscations are not
simple code layouts.
### References
6. Examine the algorithm.
[1] Astronomical algorithms (1st ed): page 59
Jean Meeus. Published by Willmann-Bell Inc.
The algorithm operates on two levels. The main visible level is
by taking a large string and breaking this down into a series of
op-codes (which I have termed J-code). These are then executed.
[2] Astronomical algorithms (1st ed): pages 285-299.
Jean Meeus. Published by Willmann-Bell Inc.
To get to the real method of how it works, you need to decode
the op-code string (which deliberately contains as many ; { and
} symbols as possible), which will give you a reverse-polish
notation chunk of mathematics.
Sensible people amongst you will simply refer to the referenced
book :-)
7. Lint it.
I no longer have lint, although I do have access to Purify. I'm
happy to say that purify does not detect any memory errors or
memory leaks.
See below for compilation warnings.
8. Compile it.
I'm sorry to say that there are several warnings issued by the
compiler.
Firstly, the return type for X() is not specified, so it
defaults to int. Horror of all horrors - this function does not
return an integer type (it doesn't contain any specific
returns). The return value from X() is not accessed. The same
problem occurs in main - it does not return. However main never
exits unless there is a serious error.
The 6th argument of XDrawText (which should be XTextItem) is
passed as a compatible structure, but without casting. This is
to reduce code space. A more elegant solution is to remove the
"struct {...} Z" completely and use "XTextItem
f={i-127+r/3*2,r%3+r/3+1,0,E}" at the start of XDrawText
block. Although this is accepted by several compilers, it is not
strict ANSI due to the non-constant initialisers. A pity.
Note that I make use of usleep(). This is a POSIX call (it is
BSD), but it supported on many systems. It may be implemented
using select() or poll() if required, or as a final solution you
may change the usleep(10000) to sleep(1). To compile on systems
which do not have usleep, but do have select, the following may
suffice as an additional compiler argument:
-Dusleep={time_t v[2]={0,10000};select(0,0,0,0,v);}
Gcc complains about "unreachable code at beginning of switch
statement", although removing some of this code will prevent
the algorithm from working.
Gcc also suggests that I should be using extra parenthesis, but
I'm taking this as good comment :-)
In addition to the above, the program has the following useful(?)
obfuscations:
1. The algorithm requires many floating point numbers (about
50). These are encoded as ASCII.
2. The J-code algorithm has op-codes designed to be space
saving. They are all one byte, but many are also considered as
white-space by the rules. This algorithm forms part of the same
string that the floating point constants are embedded
within. What does the ";" command do in J-code?
3. The J-code language is both stack based and variable based. This
"uncleanliness" is not ideal from a computer science angle, but
when has cleanliness been considered as good in IOCCC? :-)
4. Association of unconnected data by implied function usage. Eg
use of strlen() and sizeof() simply to return useful numerical
values, using irrelevant arguments.
5. As we already have a dependency on ASCII this has been abused
further. Specifically some integer constants are specified as
ASCII and some ASCII constants are integers. This hides the true
meaning for the values.
6. Red herrings: there's a couple of pieces of code whose
appearance is just there to mislead the unfirm of mind.
I've only tried to include such examples in places where at
first glance the code appears to be executed.
References
----------
[1] Astronomical algorithms (1st ed): page 59
Jean Meeus. Published by Willmann-Bell Inc.
[2] Astronomical algorithms (1st ed): pages 285-299.
Jean Meeus. Published by Willmann-Bell Inc.
[3] Skymap Pro, by Chris Marriott
http://www.skymap.com/
[3] Skymap Pro, by Chris Marriott
http://www.skymap.com/