#!/usr/bin/perl
@a=qw.$ @ substr for( shift =( gmtime |9) (_ )x7 );.;
$_=<<;s/[B-J]/$a[15&ord$&] /g;s/[A-Z_]/$a[$&lt'M']$&/g;s/\d/9-$&/eg;
P=D||BF,79;sub l{O=P-8399-D>>7;QEO/74G;O-Q+(Q>>7J};W="
";Z=l(9JREZ- l(8)JSE6+Z-R+PJT='  ';C6..0){pushK,BF13599*_,9,7}
AE(T)x74,WJLE(AI,((K,(TII,K,W),(A)x2)x5;C9..88){U=H/6G*739+_%6*0;
L[U+6,U+5]=BF_*7235199,5,5;S%=2;C8..68-(H+H>3))&8)-H==8)*(7-R))
{L[U+(6+(S/2G)*73+S++%2]=B" _",-7}}print' 'x63,"PWW L"

eval
__END__

The program prints a calendar for any year to STDOUT.
The year number is supplied on the command line. If no
year is supplied, gmtime is used to get the current year.

The main program is encrypted (sort of) and is wrapped in
a shell which reads it, decrypts it and runs it (with eval).

The shell portion starts by defining a few common strings that
will be used by the substitutions which follow. The rest of the
program is then read and decrypted by the substitutions. After
this stage, the program proper is in $_, ready to be eval'd.

If we remove redundant white space and re-arrange a few line endings, etc.
it would look like this:

$P=shift||substr gmtime,20;
sub l{$O=$P-1600-shift>>2;$Q=$O/25|0;$O-$Q+($Q>>2)};$W="\n";
$Z=l(0);$R=($Z- l(1));$S=3+$Z-$R+$P;$T='  ';for(3..9){push@K,substr
gmtime 86400*$_,0,2}@A=(($T)x25,$W);@L=((@A)x2,((@K,($T)x2)x2,@K,$W),
(@A)x7)x4;for(0..11){$U=($_/3|0)*260+$_%3*9;@L[$U+3,$U+4]=substr
gmtime$_*2764800,4,4;$S%=7;for(1..31-(($_+($_>6))&1)-($_==1)*(2-$R))
{@L[$U+(3+($S/7|0))*26+$S++%7]=substr" $_",-2}}print' 'x36,"$P$W$W @L"

This, incidentally, still fits within the 512 limit and is still fairly
obfuscated in its own right (mainly due to meaningless variable names).

After re-formatting, using meaningful variable names, adding comments,
removing some deliberate (but fairly primitive) obfuscations
and making a couple of changes to allow the -w flag we get:

#!/usr/bin/perl -w

# Select a year to print calendar for:
$year = shift				# Either from command line..
          || substr gmtime,20;		# or the current year from gmtime:
					# "Wed Jun 24 16:42:19 1998"
					#            pos 20 -->^^^^

# function to calculate number of leap years since 1600
#   takes one parameter:
#     0 - for this year (in $year)
#     1 - for last year ($year-1)
sub leap_count {
  $four_years = ($year-1600-shift)>>2;		# number of four-year blocks
  $centuries  = int($four_years/25);		# number of centuries
  $four_years - $centuries + ($centuries>>2);	# return no. of leap years
}

$leaps = leap_count(0);				# get number of leap years
						# for selected year
						
$is_leap = ($leaps - leap_count(1));		# this year is leap if the
						# leap_count for this year
						# is higher than last year
						
$start_day = ((3+$leaps-$is_leap+$year)%7);	# calculate start day (0..6)
						# for the selected year
						
$empty_cell = '  ';				# the calendar is one big
						# array of cells. change this
						# to '##' and run the program
						# again to get a better idea
						# of what is happening.
						
$newline = "\n";				# special end-of-line cell

# Fill an array with the first two characters of each day
# name using gmtime. This array is used for the labels above
# each months column of numbers. 86400 is the number of seconds in a day.
# The 3..9 represents days 3 to 9 since the epoch which happen
# to be Sunday..Saturday. This is actually equivalent to:
#   @day_names = qw(Su Mo Tu We Th Fr Sa);
for(3..9) {
  push @day_names,substr gmtime 86400*$_,0,2;	# "Wed Jun 24 16:42:19 1998"
						#  ^^<-- pos 0, length 2
}

# An empty line in the calendar array is 25 empty cells
# (7 for each of 3 months, and 2 between each of 3 months)
# and a newline
@empty_line=(($empty_cell)x25,$newline);

# The calendar is arranged as 4 rows of 3 months. Each of the 4 rows
						# starts with
@calendar=((@empty_line)x2,			# 2 empty lines (a title line
						# and a separator)
           ((@day_names,($empty_cell)x2)x2,	# a row of day name headings
	    @day_names,$newline),		# with empty cells between
	   (@empty_line)x7			# and 7 more empty lines (6
	   					# for dates and a separator)
	  )x4;					# (4 rows)

# now, fill in the dates for each month
for $month (0..11) {
  # Calculate the last day (numbered from 1) of this month
  $last_day=31-(($month+($month>6))&1)-($month==1)*(2-$is_leap);
  
  # Calculate the position in the calendar array where this month starts
  # (there are 260 cells in each row of months and 9 cells in each of
  #  the first two columns of months)
  $month_idx=int($month/3)*260+($month%3*9);

  # Fill in the month title for this month using gmtime.
  # 2764800 is the number of seconds in 32 days. 0..11 multiples
  # of 32 days from the epoch conventiently lands us in January
  # to December. The +3 selects the central(ish) cell above a month.
  # The +4 cell is set to nothing so that everything else lines up
  # nicely when printed.
  @calendar[$month_idx+3,$month_idx+4]=		# "Wed Jun 24 16:42:19 1998"
    ((substr gmtime $month*2764800,4,4),'');	#      ^^^^<-- pos 4,length 4
 
  # For each day, fill in the appropriate calendar cell
  # with a right-justified number for that day.
  for $day (1..$last_day) {
    @calendar[$month_idx+(3+int($start_day/7))*26+
    		($start_day++)%7]=sprintf"%2d",$day;
  }
  $start_day %= 7;				# start day for next month
}

# And finally, output the results:
print ' 'x36, "$year$newline$newline @calendar";

