Calendar - for "REAL" programmers

From Rosetta Code
Revision as of 02:59, 31 May 2011 by rosettacode>NevilleDNZ (→‎[[CALENDAR#ALGOL 68]]: Code example in a 6bit capable character subset - "Real Programmers Think in UPPERCASE")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Calendar - for "REAL" programmers
You are encouraged to solve this task according to the task description, using any language you may know.

Create another algorithm as per the Calendar task, except the entire code for the algorithm must be presented entirely in UPPERCASE.

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 manipulatory 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.

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' mark reserved words, it is a very early form of wikitext and make 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': (

 []'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': (
   # '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 %*:= 100;
   (D - 1 + ((M + 1) * 26) 'OVER' 10 + Y + Y 'OVER' 4 + C 'OVER' 4 - 2 * C) 'MOD' 7
 );
 'MODE' 'SIMPLEOUT' = 'UNION'('STRING', []'STRING', 'INT');
 'PROC' CPUTF = ('REF'[]'CHAR' OUT, 'FORMAT' FMT, 'SIMPLEOUT' ARGV)'VOID':(
   'FILE' F; 'STRING' S; ASSOCIATE(F,S);
   PUTF(F, (FMT, ARGV));
   OUT[:'UPB' S]:=S;
   CLOSE(F)
 );
 'PROC' MONTH REPR = ('INT' YEAR, MONTH)'MONTHBOX':(
   '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
 );
 'PROC' YEAR REPR = ('INT' YEAR)'YEARBOX':(
   '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
 );
 '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)
 ))

);

MAIN: ( '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)

)</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