How to resolve the algorithm Calendar - for REAL programmers step by step in the C programming language
How to resolve the algorithm Calendar - for REAL programmers step by step in the C programming language
Table of Contents
Problem Statement
Provide an algorithm as per the Calendar task, except the entire code for the algorithm must be presented entirely without lowercase.
Also - as per many 1969 era line printers - format the calendar to nicely fill a page that is 132 characters wide.
(Hint: manually convert the code from the Calendar task to all UPPERCASE)
This task also is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.
Moreover this task is further inspired by the long lost corollary article titled:
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 Snoopy can be found at textfiles.com. Save with a .txt extension.
Trivia: The terms uppercase and lowercase date back to the early days of the mechanical printing press. Individual metal alloy casts of each needed letter, or punctuation symbol, were meticulously added to a press block, by hand, before rolling out copies of a page. These metal casts were stored and organized in wooden cases. The more often needed minuscule letters were placed closer to hand, in the lower cases of the work bench. The less often needed, capitalized, majuscule letters, ended up in the harder to reach upper cases.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Calendar - for REAL programmers step by step in the C programming language
The program is written in C and calculates the yearly calendar. It receives two arguments: the year to print the calendar and the width of the printed calendar in characters (at least 20). If no arguments are passed, the default year is 1969 and the default width is 80 characters.
The program sets up a list of months, with their names, the number of days, the starting day of the week, and the current day of the month. It then calculates the starting day of the week for each month and sets up the layout of the calendar. The layout is based on the number of columns, the width of the calendar, and the gap between the columns.
The program then prints the calendar, row by row. Each row contains the names of the months, the days of the week, and the days of the month. The days of the month are printed in groups of seven, with a gap between each group. The calendar is printed with a leading and trailing newline character.
If the program receives invalid arguments, it prints an error message and exits with an error code.
Source code in the c programming language
/* UPPER CASE ONLY VERSION OF THE ORIGINAL CALENDAR.C, CHANGES MOSTLY TO AVOID NEEDING #INCLUDES */
/* ERROR MESSAGES GO TO STDOUT TO SLIGHTLY SIMPLIFY THE I/O HANDLING */
/* WHEN COMPILING THIS, THE COMMAND LINE SHOULD SPECIFY -D OPTIONS FOR THE FOLLOWING WORDS: */
/* STRUCT, VOID, INT, CHAR, CONST, MAIN, IF, ELSE, WHILE, FOR, DO, BREAK, RETURN, PUTCHAR */
/* THE VALUE OF EACH MACRO SHOULD BE THE WORD IN LOWER-CASE */
INT PUTCHAR(INT);
INT WIDTH = 80, YEAR = 1969;
INT COLS, LEAD, GAP;
CONST CHAR *WDAYS[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
STRUCT MONTHS {
CONST CHAR *NAME;
INT DAYS, START_WDAY, AT;
} MONTHS[12] = {
{ "JANUARY", 31, 0, 0 },
{ "FEBRUARY", 28, 0, 0 },
{ "MARCH", 31, 0, 0 },
{ "APRIL", 30, 0, 0 },
{ "MAY", 31, 0, 0 },
{ "JUNE", 30, 0, 0 },
{ "JULY", 31, 0, 0 },
{ "AUGUST", 31, 0, 0 },
{ "SEPTEMBER", 30, 0, 0 },
{ "OCTOBER", 31, 0, 0 },
{ "NOVEMBER", 30, 0, 0 },
{ "DECEMBER", 31, 0, 0 }
};
VOID SPACE(INT N) { WHILE (N-- > 0) PUTCHAR(' '); }
VOID PRINT(CONST CHAR * S){ WHILE (*S != '\0') { PUTCHAR(*S++); } }
INT STRLEN(CONST CHAR * S)
{
INT L = 0;
WHILE (*S++ != '\0') { L ++; };
RETURN L;
}
INT ATOI(CONST CHAR * S)
{
INT I = 0;
INT SIGN = 1;
CHAR C;
WHILE ((C = *S++) != '\0') {
IF (C == '-')
SIGN *= -1;
ELSE {
I *= 10;
I += (C - '0');
}
}
RETURN I * SIGN;
}
VOID INIT_MONTHS(VOID)
{
INT I;
IF ((!(YEAR % 4) && (YEAR % 100)) || !(YEAR % 400))
MONTHS[1].DAYS = 29;
YEAR--;
MONTHS[0].START_WDAY
= (YEAR * 365 + YEAR/4 - YEAR/100 + YEAR/400 + 1) % 7;
FOR (I = 1; I < 12; I++)
MONTHS[I].START_WDAY =
(MONTHS[I-1].START_WDAY + MONTHS[I-1].DAYS) % 7;
COLS = (WIDTH + 2) / 22;
WHILE (12 % COLS) COLS--;
GAP = COLS - 1 ? (WIDTH - 20 * COLS) / (COLS - 1) : 0;
IF (GAP > 4) GAP = 4;
LEAD = (WIDTH - (20 + GAP) * COLS + GAP + 1) / 2;
YEAR++;
}
VOID PRINT_ROW(INT ROW)
{
INT C, I, FROM = ROW * COLS, TO = FROM + COLS;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
I = STRLEN(MONTHS[C].NAME);
SPACE((20 - I)/2);
PRINT(MONTHS[C].NAME);
SPACE(20 - I - (20 - I)/2 + ((C == TO - 1) ? 0 : GAP));
}
PUTCHAR('\012');
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < 7; I++) {
PRINT(WDAYS[I]);
PRINT(I == 6 ? "" : " ");
}
IF (C < TO - 1) SPACE(GAP);
ELSE PUTCHAR('\012');
}
WHILE (1) {
FOR (C = FROM; C < TO; C++)
IF (MONTHS[C].AT < MONTHS[C].DAYS) BREAK;
IF (C == TO) BREAK;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < MONTHS[C].START_WDAY; I++) SPACE(3);
WHILE(I++ < 7 && MONTHS[C].AT < MONTHS[C].DAYS) {
INT MM = ++MONTHS[C].AT;
PUTCHAR((MM < 10) ? ' ' : '0' + (MM /10));
PUTCHAR('0' + (MM %10));
IF (I < 7 || C < TO - 1) PUTCHAR(' ');
}
WHILE (I++ <= 7 && C < TO - 1) SPACE(3);
IF (C < TO - 1) SPACE(GAP - 1);
MONTHS[C].START_WDAY = 0;
}
PUTCHAR('\012');
}
PUTCHAR('\012');
}
VOID PRINT_YEAR(VOID)
{
INT Y = YEAR;
INT ROW;
CHAR BUF[32];
CHAR * B = &(BUF[31]);
*B-- = '\0';
DO {
*B-- = '0' + (Y % 10);
Y /= 10;
} WHILE (Y > 0);
B++;
SPACE((WIDTH - STRLEN(B)) / 2);
PRINT(B);PUTCHAR('\012');PUTCHAR('\012');
FOR (ROW = 0; ROW * COLS < 12; ROW++)
PRINT_ROW(ROW);
}
INT MAIN(INT C, CHAR **V)
{
INT I, YEAR_SET = 0, RESULT = 0;
FOR (I = 1; I < C && RESULT == 0; I++) {
IF (V[I][0] == '-' && V[I][1] == 'W' && V[I][2] == '\0') {
IF (++I == C || (WIDTH = ATOI(V[I])) < 20)
RESULT = 1;
} ELSE IF (!YEAR_SET) {
YEAR = ATOI(V[I]);
IF (YEAR <= 0)
YEAR = 1969;
YEAR_SET = 1;
} ELSE
RESULT = 1;
}
IF (RESULT == 0) {
INIT_MONTHS();
PRINT_YEAR();
} ELSE {
PRINT("BAD ARGS\012USAGE: ");
PRINT(V[0]);
PRINT(" YEAR [-W WIDTH (>= 20)]\012");
}
RETURN RESULT;
}
You may also check:How to resolve the algorithm Draw a pixel step by step in the Microsoft Small Basic programming language
You may also check:How to resolve the algorithm Morse code step by step in the Ring programming language
You may also check:How to resolve the algorithm Sum and product of an array step by step in the Joy programming language
You may also check:How to resolve the algorithm Dinesman's multiple-dwelling problem step by step in the Ceylon programming language
You may also check:How to resolve the algorithm Sum and product of an array step by step in the Bracmat programming language