132 lines
3 KiB
Text
132 lines
3 KiB
Text
MODULE CistercianNumerals;
|
|
FROM STextIO IMPORT
|
|
WriteLn, WriteString;
|
|
FROM SWholeIO IMPORT
|
|
WriteInt;
|
|
|
|
CONST
|
|
MaxCoord = 14;
|
|
|
|
TYPE
|
|
TCanvas = ARRAY [0 .. MaxCoord], [0 .. MaxCoord] OF CHAR;
|
|
TSignVals = [-1 .. 1];
|
|
|
|
(* BEGIN. Operations on the TCanvas ADT. *)
|
|
PROCEDURE ClearCanvas(VAR Canvas: TCanvas);
|
|
VAR
|
|
I, J: CARDINAL;
|
|
BEGIN
|
|
FOR I := 0 TO MaxCoord DO
|
|
FOR J := 0 TO MaxCoord DO
|
|
Canvas[I, J] := ' '
|
|
END
|
|
END
|
|
END ClearCanvas;
|
|
|
|
PROCEDURE DrawLine(VAR Canvas: TCanvas; R0, C0: CARDINAL;
|
|
Dist: CARDINAL; DR, DC: TSignVals);
|
|
(* Draws a straight (vertical, horizontal, or diagonal) line
|
|
from Canvas[R0, C0] to Canvas[R0 + DR * Dist, C0 + DC * Dist]. *)
|
|
VAR
|
|
C, R, I: CARDINAL;
|
|
BEGIN
|
|
R := R0; C := C0;
|
|
FOR I := 0 TO Dist DO
|
|
Canvas[R, C] := '*';
|
|
R := INT(R) + DR; C := INT(C) + DC;
|
|
END
|
|
END DrawLine;
|
|
|
|
PROCEDURE ShowCanvas(VAR Canvas: TCanvas);
|
|
VAR
|
|
I, J: CARDINAL;
|
|
Row: ARRAY [0 .. MaxCoord + 1] OF CHAR;
|
|
BEGIN
|
|
FOR I := 0 TO MaxCoord DO
|
|
FOR J := 0 TO MaxCoord DO
|
|
Row[J] := Canvas[I, J]
|
|
END;
|
|
Row[MaxCoord + 1] := CHR(0);
|
|
WriteString(Row);
|
|
WriteLn
|
|
END
|
|
END ShowCanvas;
|
|
(* END Operations on the TCanvas ADT. *)
|
|
|
|
PROCEDURE DrawNumber(VAR Canvas: TCanvas; V: CARDINAL);
|
|
(* DrawDigit is part of the algorithm, so it is nested in DrawNumber. *)
|
|
TYPE
|
|
TDigits = [0 .. 9];
|
|
VAR
|
|
Thousands, Hundreds, Tens, Ones: CARDINAL;
|
|
RAxis, CAxis: CARDINAL;
|
|
|
|
PROCEDURE DrawDigit(V: TDigits; RS, CS: TSignVals);
|
|
(* RS, CS are signs of rows and cols in in relation to the axis.
|
|
They decide in which quadrant a digit is located. *)
|
|
VAR
|
|
IRS, ICS: CARDINAL;
|
|
BEGIN
|
|
IRS := INT(RS);
|
|
ICS := INT(CS);
|
|
CASE V OF
|
|
| 1: DrawLine(Canvas, RAxis + IRS * 7, CAxis + ICS, 4, 0, CS)
|
|
| 2: DrawLine(Canvas, RAxis + IRS * 3, CAxis + ICS, 4, 0, CS)
|
|
| 3: DrawLine(Canvas, RAxis + IRS * 7, CAxis + ICS, 4, -RS, CS)
|
|
| 4: DrawLine(Canvas, RAxis + IRS * 3, CAxis + ICS, 4, RS, CS)
|
|
| 5: DrawDigit(1, RS, CS); DrawDigit(4, RS, CS)
|
|
| 6: DrawLine(Canvas, RAxis + IRS * 3, CAxis + ICS * 5, 4, RS, 0)
|
|
| 7: DrawDigit(1, RS, CS); DrawDigit(6, RS, CS)
|
|
| 8: DrawDigit(2, RS, CS); DrawDigit(6, RS, CS)
|
|
| 9: DrawDigit(1, RS, CS); DrawDigit(8, RS, CS)
|
|
ELSE
|
|
END;
|
|
END DrawDigit;
|
|
|
|
BEGIN (*DrawNumber *)
|
|
RAxis := MaxCoord DIV 2;
|
|
CAxis := 5;
|
|
DrawLine(Canvas, 0, CAxis, MaxCoord, 1, 0); (* Draw 0 (or vertical axis) *)
|
|
Thousands := V DIV 1000;
|
|
V := V MOD 1000;
|
|
Hundreds := V DIV 100;
|
|
V := V MOD 100;
|
|
Tens := V DIV 10;
|
|
Ones := V MOD 10;
|
|
IF Thousands > 0 THEN
|
|
DrawDigit(Thousands, 1, -1)
|
|
END;
|
|
IF Hundreds > 0 THEN
|
|
DrawDigit(Hundreds, 1, 1)
|
|
END;
|
|
IF Tens > 0 THEN
|
|
DrawDigit(Tens, -1, -1)
|
|
END;
|
|
IF Ones > 0 THEN
|
|
DrawDigit(Ones, -1, 1)
|
|
END;
|
|
END DrawNumber;
|
|
|
|
PROCEDURE Test(N: CARDINAL);
|
|
VAR
|
|
Canvas: TCanvas;
|
|
BEGIN
|
|
WriteInt(N, 1);
|
|
WriteString(':');
|
|
WriteLn;
|
|
ClearCanvas(Canvas);
|
|
DrawNumber(Canvas, N);
|
|
ShowCanvas(Canvas);
|
|
WriteLn;
|
|
END Test;
|
|
|
|
BEGIN
|
|
Test(0);
|
|
Test(1);
|
|
Test(20);
|
|
Test(300);
|
|
Test(4000);
|
|
Test(5555);
|
|
Test(6789);
|
|
Test(9999);
|
|
END CistercianNumerals.
|