Calendar - for "REAL" programmers

Provide an algorithm as per the Calendar task, except the entire code for the algorithm must be presented entirely without lowercase. (Hint: manually convert the code from the Calendar task to all UPPERCASE)

Task
Calendar - for "REAL" programmers
You are encouraged to solve this task according to the task description, using any language you may know.

This task also is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.

THE REAL PROGRAMMER'S NATURAL HABITAT
"Taped to the wall is a line-printer Snoopy calender for the year 1969."

Moreover this task is further inspired by the long lost corollary article titled:

"Real programmers think in UPPERCASE"!

Note: Whereas today we only need to worry about ASCII, UTF-8, UTF-16, UTF-32, UTF-7 and UTF-EBCDIC encodings, in the 1960s having code in UPPERCASE was often mandatory as characters were often stuffed into 36-bit words as 6 lots of 6-bit characters. More extreme words sizes include 60-bit words of the CDC 6000 series computers. The Soviets even had a national character set that was inclusive of all 4-bit, 5-bit, 6-bit & 7-bit depending on how the file was opened... And one rogue Soviet university went further and built a 1.5-bit based computer.

Of course... as us Boomers have turned into Geezers we have become HARD OF HEARING, and suffer from chronic Presbyopia, hence programming in UPPERCASE is less to do with computer architecture and more to do with practically. :-)

For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.

FYI: a nice ASCII art file of Snoppy can be found at textfiles.com. Save with a .txt extension.

Ada

Uses the package "Printable_Calendar" from the Ada solution of the calendar task:

<lang Ada>with Printable_Calendar;

procedure Real_Cal is

  C: Printable_Calendar.Calendar := Printable_Calendar.Init_132
    ((Weekday_Rep =>
         "MO TU WE TH FR SA SO",
      Month_Rep   =>
        ("      JANUARY       ", "      FEBRUARY      ",
         "       MARCH        ", "       APRIL        ",
         "        MAY         ", "        JUNE        ",
         "        JULY        ", "       AUGUST       ",
         "      SEPTEMBER     ", "       OCTOBER      ",
         "      NOVEMBER      ", "      DECEMBER      ")
     ));

begin

  C.Print_Line_Centered("[SNOOPY]");
  C.New_Line;
  C.Print(1969, "1969");

end Real_Cal;</lang>

Output:

                                                             [SNOOPY]                                                             

                                                               1969                                                               

       JANUARY               FEBRUARY               MARCH                 APRIL                  MAY                   JUNE        
 MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO
        1  2  3  4  5                  1  2                  1  2      1  2  3  4  5  6            1  2  3  4                     1
  6  7  8  9 10 11 12   3  4  5  6  7  8  9   3  4  5  6  7  8  9   7  8  9 10 11 12 13   5  6  7  8  9 10 11   2  3  4  5  6  7  8
 13 14 15 16 17 18 19  10 11 12 13 14 15 16  10 11 12 13 14 15 16  14 15 16 17 18 19 20  12 13 14 15 16 17 18   9 10 11 12 13 14 15
 20 21 22 23 24 25 26  17 18 19 20 21 22 23  17 18 19 20 21 22 23  21 22 23 24 25 26 27  19 20 21 22 23 24 25  16 17 18 19 20 21 22
 27 28 29 30 31        24 25 26 27 28        24 25 26 27 28 29 30  28 29 30              26 27 28 29 30 31     23 24 25 26 27 28 29
                                             31                                                                30                  

         JULY                 AUGUST               SEPTEMBER              OCTOBER              NOVEMBER              DECEMBER      
 MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO  MO TU WE TH FR SA SO
     1  2  3  4  5  6               1  2  3   1  2  3  4  5  6  7         1  2  3  4  5                  1  2   1  2  3  4  5  6  7
  7  8  9 10 11 12 13   4  5  6  7  8  9 10   8  9 10 11 12 13 14   6  7  8  9 10 11 12   3  4  5  6  7  8  9   8  9 10 11 12 13 14
 14 15 16 17 18 19 20  11 12 13 14 15 16 17  15 16 17 18 19 20 21  13 14 15 16 17 18 19  10 11 12 13 14 15 16  15 16 17 18 19 20 21
 21 22 23 24 25 26 27  18 19 20 21 22 23 24  22 23 24 25 26 27 28  20 21 22 23 24 25 26  17 18 19 20 21 22 23  22 23 24 25 26 27 28
 28 29 30 31           25 26 27 28 29 30 31  29 30                 27 28 29 30 31        24 25 26 27 28 29 30  29 30 31

To change the output to 80-character devices, replace "Init_132" by "Init_80".

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny.

This code uses 'quote stropping' to mark reserved words, it is a very early form of wikitext and makes syntax highlighting of source code for publication relatively easy.

Note: to run this code with ALGOL 68G you need to use the --quote-stropping option. <lang algol68>'PR' QUOTE 'PR'

'PROC' PRINT CALENDAR = ('INT' YEAR, PAGE WIDTH)'VOID': 'BEGIN'

 ()'STRING' MONTH NAMES = (
     "JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE",
     "JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"),
   WEEKDAY NAMES = ("SU","MO","TU","WE","TH","FR","SA");
 'FORMAT' WEEKDAY FMT = $G,N('UPB' WEEKDAY NAMES - 'LWB' WEEKDAY NAMES)(" "G)$;

 # 'JUGGLE' THE CALENDAR FORMAT TO FIT THE PRINTER/SCREEN WIDTH #
 'INT' DAY WIDTH = 'UPB' WEEKDAY NAMES(1), DAY GAP=1;
 'INT' MONTH WIDTH = (DAY WIDTH+DAY GAP) * 'UPB' WEEKDAY NAMES-1;
 'INT' MONTH HEADING LINES = 2;
 'INT' MONTH LINES = (31 'OVER' 'UPB' WEEKDAY NAMES+MONTH HEADING LINES+2); # +2 FOR HEAD/TAIL WEEKS #
 'INT' YEAR COLS = (PAGE WIDTH+1) 'OVER' (MONTH WIDTH+1);
 'INT' YEAR ROWS = ('UPB' MONTH NAMES-1)'OVER' YEAR COLS + 1;
 'INT' MONTH GAP = (PAGE WIDTH - YEAR COLS*MONTH WIDTH + 1)'OVER' YEAR COLS;
 'INT' YEAR WIDTH = YEAR COLS*(MONTH WIDTH+MONTH GAP)-MONTH GAP;
 'INT' YEAR LINES = YEAR ROWS*MONTH LINES;

 'MODE' 'MONTHBOX' = (MONTH LINES, MONTH WIDTH)'CHAR';
 'MODE' 'YEARBOX'  = (YEAR  LINES, YEAR  WIDTH)'CHAR';

 'INT' WEEK START = 1; # 'SUNDAY' #

 'PROC' DAYS IN MONTH = ('INT' YEAR, MONTH)'INT':
   'CASE' MONTH 'IN' 31,
     'IF' YEAR 'MOD' 4 'EQ' 0 'AND' YEAR 'MOD' 100 'NE' 0 'OR' YEAR 'MOD' 400 'EQ' 0 'THEN' 29 'ELSE' 28 'FI',
     31, 30, 31, 30, 31, 31, 30, 31, 30, 31
   'ESAC';

 'PROC' DAY OF WEEK = ('INT' YEAR, MONTH, DAY)'INT': 'BEGIN'
   # 'DAY' OF THE WEEK BY 'ZELLER'’S 'CONGRUENCE' ALGORITHM FROM 1887 #
   'INT' Y := YEAR, M := MONTH, D := DAY, C;
   'IF' M <= 2 'THEN' M +:= 12; Y -:= 1 'FI';
   C := Y 'OVER' 100;
   Y 'MODAB' 100;
   (D - 1 + ((M + 1) * 26) 'OVER' 10 + Y + Y 'OVER' 4 + C 'OVER' 4 - 2 * C) 'MOD' 7
 'END';

 'MODE' 'SIMPLEOUT' = 'UNION'('STRING', ()'STRING', 'INT');

 'PROC' CPUTF = ('REF'()'CHAR' OUT, 'FORMAT' FMT, 'SIMPLEOUT' ARGV)'VOID':'BEGIN'
   'FILE' F; 'STRING' S; ASSOCIATE(F,S);
   PUTF(F, (FMT, ARGV));
   OUT(:'UPB' S):=S;
   CLOSE(F)
 'END';

 'PROC' MONTH REPR = ('INT' YEAR, MONTH)'MONTHBOX':'BEGIN'
   'MONTHBOX' MONTH BOX; 'FOR' LINE 'TO' 'UPB' MONTH BOX 'DO' MONTH BOX(LINE,):=" "* 2 'UPB' MONTH BOX 'OD';
   'STRING' MONTH NAME = MONTH NAMES(MONTH);

 # CENTER THE TITLE #
   CPUTF(MONTH BOX(1,(MONTH WIDTH - 'UPB' MONTH NAME ) 'OVER' 2+1:), $G$, MONTH NAME);
   CPUTF(MONTH BOX(2,), WEEKDAY FMT, WEEKDAY NAMES);

   'INT' FIRST DAY := DAY OF WEEK(YEAR, MONTH, 1);
   'FOR' DAY 'TO' DAYS IN MONTH(YEAR, MONTH) 'DO'
     'INT' LINE = (DAY+FIRST DAY-WEEK START) 'OVER' 'UPB' WEEKDAY NAMES + MONTH HEADING LINES + 1;
     'INT' CHAR =((DAY+FIRST DAY-WEEK START) 'MOD' 'UPB' WEEKDAY NAMES)*(DAY WIDTH+DAY GAP) + 1;
     CPUTF(MONTH BOX(LINE,CHAR:CHAR+DAY WIDTH-1),$G(-DAY WIDTH)$, DAY)
   'OD';
   MONTH BOX
 'END';

 'PROC' YEAR REPR = ('INT' YEAR)'YEARBOX':'BEGIN'
   'YEARBOX' YEAR BOX;
   'FOR' LINE 'TO' 'UPB' YEAR BOX 'DO' YEAR BOX(LINE,):=" "* 2 'UPB' YEAR BOX 'OD';
   'FOR' MONTH ROW 'FROM' 0 'TO' YEAR ROWS-1 'DO'
     'FOR' MONTH COL 'FROM' 0 'TO' YEAR COLS-1 'DO'
       'INT' MONTH = MONTH ROW * YEAR COLS + MONTH COL + 1;
       'IF' MONTH > 'UPB' MONTH NAMES 'THEN'
         DONE
       'ELSE'
         'INT' MONTH COL WIDTH = MONTH WIDTH+MONTH GAP;
         YEAR BOX(
           MONTH ROW*MONTH LINES+1 : (MONTH ROW+1)*MONTH LINES,
           MONTH COL*MONTH COL WIDTH+1 : (MONTH COL+1)*MONTH COL WIDTH-MONTH GAP
         ) := MONTH REPR(YEAR, MONTH)
       'FI'
     'OD'
   'OD';
   DONE: YEAR BOX
 'END';

 'INT' CENTER = (YEAR COLS*(MONTH WIDTH+MONTH GAP) - MONTH GAP - 1) 'OVER' 2;
 'INT' INDENT = (PAGE WIDTH - YEAR WIDTH) 'OVER' 2;

 PRINTF((
   $N(INDENT + CENTER - 9)K  G L$, "(INSERT SNOOPY HERE)",
   $N(INDENT + CENTER - 1)K 4D L$, YEAR, $L$,
   $N(INDENT)K N(YEAR WIDTH)(G)  L$, YEAR REPR(YEAR)
 ))

'END';

MAIN: 'BEGIN' 'CO' INSPIRED BY HTTP://WWW.EE.RYERSON.CA/~ELF/hack/realmen.html

          REAL PROGRAMMERS DONT USE PASCAL - ED POST
           DATAMATION, VOLUME 29 NUMBER 7, JULY 1983
             THE REAL PROGRAMMERS NATURAL HABITAT

"TAPED TO THE WALL IS A LINE-PRINTER SNOOPY CALENDER FOR THE YEAR 1969" 'CO'

 'INT' MANKIND STEPPED ON THE MOON = 1969,
     LINE PRINTER WIDTH = 132; # AS AT 1969! #
 PRINT CALENDAR(MANKIND STEPPED ON THE MOON, LINE PRINTER WIDTH)

'END'</lang> Output:

                                                       (INSERT SNOOPY HERE)
                                                               1969

      JANUARY               FEBRUARY               MARCH                 APRIL                  MAY                   JUNE        
SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA
          1  2  3  4                     1                     1         1  2  3  4  5               1  2  3   1  2  3  4  5  6  7
 5  6  7  8  9 10 11   2  3  4  5  6  7  8   2  3  4  5  6  7  8   6  7  8  9 10 11 12   4  5  6  7  8  9 10   8  9 10 11 12 13 14
12 13 14 15 16 17 18   9 10 11 12 13 14 15   9 10 11 12 13 14 15  13 14 15 16 17 18 19  11 12 13 14 15 16 17  15 16 17 18 19 20 21
19 20 21 22 23 24 25  16 17 18 19 20 21 22  16 17 18 19 20 21 22  20 21 22 23 24 25 26  18 19 20 21 22 23 24  22 23 24 25 26 27 28
26 27 28 29 30 31     23 24 25 26 27 28     23 24 25 26 27 28 29  27 28 29 30           25 26 27 28 29 30 31  29 30               
                                            30 31                                                                                 
        JULY                 AUGUST              SEPTEMBER              OCTOBER               NOVEMBER              DECEMBER      
SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA
       1  2  3  4  5                  1  2      1  2  3  4  5  6            1  2  3  4                     1      1  2  3  4  5  6
 6  7  8  9 10 11 12   3  4  5  6  7  8  9   7  8  9 10 11 12 13   5  6  7  8  9 10 11   2  3  4  5  6  7  8   7  8  9 10 11 12 13
13 14 15 16 17 18 19  10 11 12 13 14 15 16  14 15 16 17 18 19 20  12 13 14 15 16 17 18   9 10 11 12 13 14 15  14 15 16 17 18 19 20
20 21 22 23 24 25 26  17 18 19 20 21 22 23  21 22 23 24 25 26 27  19 20 21 22 23 24 25  16 17 18 19 20 21 22  21 22 23 24 25 26 27
27 28 29 30 31        24 25 26 27 28 29 30  28 29 30              26 27 28 29 30 31     23 24 25 26 27 28 29  28 29 30 31         
                      31                                                                30                                        

GUISS

In Graphical User Interface Support Script, we utilize applications that are already written. So for this task, we shall just display the calendar that sets the system clock.

<lang guiss>RIGHTCLICK:CLOCK,ADJUST DATE AND TIME,BUTTON:CANCEL</lang>

Icon and Unicon

Icon and Unicon don't lend themselves to REAL programming in the sense of this task easily. And initially this task was marked omit because the primary declarations, reserved words, and the name of the main procedure are all in lowercase. However, getting in the spirit of the task real programmers do not give up and a number of solutions are possible:

  • A real programmer could write a preprocessor to eliminate lower case or insert before translation the one unreal line needed to realize this solution
  • An uber-real programmer would rewrite the entire translator
  • Or, a real programmer could do what's presented below on a coffee break with the preprocessor

In the example,

  • we must concede lowercase letters for the preprocessor directive $include (although as noted a preprocessor could handle this)
  • we temporarily concede the lowercase letters needed to realize the IPL procedures IsLeapYear and julian; however, a real programmer could easily rewrite these in a more real format (or an uber-real programmer would just rewrite the IPL
  • the character set usage has been reduced from 69 unique characters to 51 (within 6 bit character representations) by the following tactics:
    • elimination of # and all comments as real programmers don't need them
    • use of preprocessor definitions to eliminate the need for {[]}
    • use of char (excuse me CHAR) to generate characters such as "\n"
    • elimination of tabs for blanks

Now clearly all of these measures will make the storage, interpretation, and comprehension of this program more real and efficient for real programmers like us.

Oh, dear. It seems I have written documentation to explain what I have done. Tisk. Tisk. Someone come take my real programmer epaulettes away. And, you! Since you've read this you must surrender your stripes too.

Also it makes me go all nostalgic for my old WATFIVE compiler. And an IBM 129 keypunch. And 5 hole paper tape.

<lang Unicon>$include "REALIZE.ICN"

LINK DATETIME $define ISLEAPYEAR IsLeapYear $define JULIAN julian

PROCEDURE MAIN(A) PRINTCALENDAR(\A$<1$>|1969) END

PROCEDURE PRINTCALENDAR(YEAR)

  COLS := 3                                        
  MONS := $<$>                                       
  "JANUARY FEBRUARY MARCH APRIL MAY JUNE " || 
  "JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER " ?
         WHILE PUT(MONS, TAB(FIND(" "))) DO MOVE(1)    
  WRITE(CENTER("$<SNOOPY PICTURE$>",COLS * 24 + 4))  
  WRITE(CENTER(YEAR,COLS * 24 + 4), CHAR(10))          
  
  M := LIST(COLS)	                                        
  EVERY  MON := 0 TO 9 BY COLS DO $(               
     WRITES("    ")
     EVERY I := 1 TO COLS DO {
        WRITES(CENTER(MONS$<MON+I$>,24))             
        M$<I$> := CREATE CALENDARFORMATWEEK(1969,MON + I)  
        $)
     WRITE()
     EVERY 1 TO 7 DO $(                                      
        EVERY C := 1 TO COLS DO $(                 
           WRITES("    ")
           EVERY 1 TO 7 DO WRITES(RIGHT(@M$<C$>,3))  
           $)
        WRITE()
        $)
     $)

END

PROCEDURE CALENDARFORMATWEEK(YEAR,M) STATIC D INITIAL D := $<31,28,31,30,31,30,31,31,30,31,30,31$>

EVERY SUSPEND "SU"|"MO"|"TU"|"WE"|"TH"|"FR"|"SA" EVERY 1 TO (DAY := (JULIAN(M,1,YEAR)+1)%7) DO SUSPEND "" EVERY SUSPEND 1 TO D$<M$> DO DAY +:= 1 IF M = 2 & ISLEAPYEAR(YEAR) THEN SUSPEND (DAY +:= 1, 29) EVERY DAY TO (6*7) DO SUSPEND "" END</lang>

Where REALIZE.ICN would be something like this (this example is incomplete but sufficient for this program):

<lang Icon>$define PROCEDURE procedure $define END end $define WRITE write $define WRITES writes $define SUSPEND suspend $define DO do $define TO to $define EVERY every $define LIST list $define WHILE while $define MAIN main $define PUT put $define TAB tab $define MOVE move $define CHAR move $define CENTER center $define RIGHT right $define FIND find $define STATIC static $define INITIAL initial $define CREATE create $define LINK link $define IF if $define THEN then $define BY by</lang>

DATETIME.ICN provides IsLeapYear and julian

J

After some sneaky code with foreigns to obtain the upper and lowercase alphabets (because a. cannot be used), the code is straightforward. Write names in uppercase, convert to lowercase, and then use ~ to make the strings into verbs. Code taken from the calendar page.

Solution: <lang j> 'UPPER LOWER'=: 3 (3!:4)"1 ]65 97 +/ <:+/\26$1 NB. UPPER AND LOWERCASE ALPHABETS

  TL=:(LOWER {~ [: {.@I. 1,~UPPER&=) :: ]"0 NB. TO LOWERCASE
  TU=:(UPPER {~ [: {.@I. 1,~LOWER&=) :: ]"0 NB. TO UPPERCASE
  (TL 'REQUIRE')~ TL'DATES FORMAT' NB. J6
  (TL 'REQUIRE')~ TL'DATES GENERAL/MISC/FORMAT'  NB. J7
  CALBODY=: (1 1 }. _1 _1 }. ":)@(-@(<.@%&22)@[ ]\ ((TL'CALENDAR')~)@])
  CALTITLE=: (<: - 22&|)@[ ((TL'CENTER')~) '[INSERT SNOOPY HERE]' ,  ,:~ ":@]
  FORMATCALENDAR=: [: TU CALTITLE,CALBODY</lang>

Example use: <lang j> 80 FORMATCALENDAR 1969

                     [INSERT SNOOPY HERE]                       
                             1969                               
                                                                
        JAN         │         FEB         │         MAR         
SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA
          1  2  3  4│                    1│                    1
 5  6  7  8  9 10 11│  2  3  4  5  6  7  8│  2  3  4  5  6  7  8
12 13 14 15 16 17 18│  9 10 11 12 13 14 15│  9 10 11 12 13 14 15
19 20 21 22 23 24 25│ 16 17 18 19 20 21 22│ 16 17 18 19 20 21 22
26 27 28 29 30 31   │ 23 24 25 26 27 28   │ 23 24 25 26 27 28 29
                    │                     │ 30 31               

─────────────────────┼─────────────────────┼─────────────────────

        APR         │         MAY         │         JUN         
SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA
       1  2  3  4  5│              1  2  3│  1  2  3  4  5  6  7
 6  7  8  9 10 11 12│  4  5  6  7  8  9 10│  8  9 10 11 12 13 14
13 14 15 16 17 18 19│ 11 12 13 14 15 16 17│ 15 16 17 18 19 20 21
20 21 22 23 24 25 26│ 18 19 20 21 22 23 24│ 22 23 24 25 26 27 28
27 28 29 30         │ 25 26 27 28 29 30 31│ 29 30               
                    │                     │                     

─────────────────────┼─────────────────────┼─────────────────────

        JUL         │         AUG         │         SEP         
SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA
       1  2  3  4  5│                 1  2│     1  2  3  4  5  6
 6  7  8  9 10 11 12│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13
13 14 15 16 17 18 19│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20
20 21 22 23 24 25 26│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27
27 28 29 30 31      │ 24 25 26 27 28 29 30│ 28 29 30            
                    │ 31                  │                     

─────────────────────┼─────────────────────┼─────────────────────

        OCT         │         NOV         │         DEC         
SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA│ SU MO TU WE TH FR SA
          1  2  3  4│                    1│     1  2  3  4  5  6
 5  6  7  8  9 10 11│  2  3  4  5  6  7  8│  7  8  9 10 11 12 13
12 13 14 15 16 17 18│  9 10 11 12 13 14 15│ 14 15 16 17 18 19 20
19 20 21 22 23 24 25│ 16 17 18 19 20 21 22│ 21 22 23 24 25 26 27
26 27 28 29 30 31   │ 23 24 25 26 27 28 29│ 28 29 30 31         
                    │ 30                  │                     </lang>

Perl

Since we can't use eval or print (or any other keywords) at the top level, we need to abuse backticks in order to print anything, as in the infamous JAPH with no letters or numbers. Consequently, the calendar is printed to standard error instead of standard output.

<lang perl>$PROGRAM = '\'

MY @START_DOW = (3, 6, 6, 2, 4, 0,

                2, 5, 1, 3, 6, 1);

MY @DAYS = (31, 28, 31, 30, 31, 30,

           31, 31, 30, 31, 30, 31);

MY @MONTHS; FOREACH MY $M (0 .. 11) {

   FOREACH MY $R (0 .. 5) {
       $MONTHS[$M][$R] = JOIN " ",
           MAP { $_ < 1 || $_ > $DAYS[$M] ? "  " : SPRINTF "%2D", $_ }
           MAP { $_ - $START_DOW[$M] + 1 }
           $R * 7 .. $R * 7 + 6;
   }

}

SUB P { WARN $_[0], "\\N" } P UC " [INSERT SNOOPY HERE]"; P " 1969"; P ""; FOREACH (UC(" JANUARY FEBRUARY MARCH APRIL MAY JUNE"),

        UC("        JULY                 AUGUST              SEPTEMBER              OCTOBER               NOVEMBER              DECEMBER")) {
   P $_;
   MY @MS = SPLICE @MONTHS, 0, 6;
   P JOIN "  ", ((UC "SU MO TU WE TH FR SA") X 6);
   P JOIN "  ", MAP { SHIFT @$_ } @MS FOREACH 0 .. 5;

}

\;

  1. LOWERCASE LETTERS

$E = '%' | '@'; $C = '#' | '@'; $H = '(' | '@'; $O = '/' | '@'; $T = '4' | '@'; $R = '2' | '@'; $A = '!' | '@'; $Z = ':' | '@'; $P = '0' | '@'; $L = ',' | '@';

`${E}${C}${H}${O} $PROGRAM | ${T}${R} A-Z ${A}-${Z} | ${P}${E}${R}${L}`;</lang> Although, if we are abusing the backticks and other innocent programs, why not just: <lang Perl>$_=$ARGV[0]//1969;`\143\141\154 $_ >&2`</lang>

Perl 6

Uppercase is no challenge, who needs letters at all?

Works with: rakudo version 2011.07

[Requires the year to be supplied as a command-line argument, Snoopy to be available in snoopy.txt, and Unixish cat and cal commands.] <lang perl6>$_=["\0"..."~"];< 114 117 110 32 34 99 97 116 32 115 110 111 111 112 121 46 116 120 116 59 99 97 108 32 64 42 65 82 71 83 91 48 93 34 >."$_[99]$_[104]$_[114]$_[115]"()."$_[101]$_[118]$_[97]$_[108]"()</lang>

PicoLisp

The "CALENDAR.L" source file: <lang PicoLisp>(DE CAL (YEAR)

  (PRINL "====== " YEAR " ======")
  (FOR DAT (RANGE (DATE YEAR 1 1) (DATE YEAR 12 31))
     (LET D (DATE DAT)
        (TAB (3 3 4 8)
           (WHEN (= 1 (CADDR D))
              (GET `(INTERN (PACK (MAPCAR CHAR (42 77 111 110)))) (CADR D)) )
           (CADDR D)
           (DAY DAT `(INTERN (PACK (MAPCAR CHAR (42 68 97 121)))))
           (WHEN (=0 (% (INC DAT) 7))
              (PACK (CHAR 87) "EEk " (WEEK DAT)) ) ) ) ) )

(CAL 1969) (BYE)</lang> Then it can be executed with this command line:

$ pil -'load (list "awk" "{print tolower($0)}" "CALENDAR.L")'

Output:

====== 1969 ======
Jan  1 Wed
     2 Thu
     3 Fri
     4 Sat
     5 Sun
     6 Mon  Week 2
     7 Tue
....
    28 Sat
    29 Sun
    30 Mon Week 27
Jul  1 Tue
     2 Wed
     3 Thu
     4 Fri
....
    25 Thu
    26 Fri
    27 Sat
    28 Sun
    29 Mon Week 53
    30 Tue
    31 Wed