program PowerTab; {Display powers of a (mod m)} {$N+,E+} uses CRT, Printer, nothy; {$I GetInput.i } const MaxJ = 99980; PrinterLimit = 60; {Limit on the number of lines in the printed table} MaxMod = 999999; {Must have m < 1E6 so that entries fit on the screen} var a, {base of which powers are to be computed} b, {base reduced modulo m} m {modulus} : comp; x : extended; i, j, k {indices of the powers} : longint; pwr {pwr[i] = a^(10j + i) (mod m)} : array[0..199] of comp; OriginalMode {Save original screen mode for restoration} : word; Ch : char; {Answer to prompt} funckey, {was a function key pressed?} inputok {is the input acceptable?} : boolean; procedure Display(j : longint); {display the powers, starting at 10j} var p {power entered in table} : comp; St : string[20]; h, i, {indices} l, {length of a string} ind {amount to indent by} : integer; begin TextColor(15); TextBackground(0); ClrScr; Str(a:1:0, St); l := Length(St); Str(m:1:0, St); l := l + Length(St); ind := (63 - l) div 2; {amount to indent by, to center title} GoToXY(ind, 1); WriteLn('POWERS OF ', a:1:0, ' (MOD ', m:1:0, ')'); WriteLn; Write(' j 10j 10j+1 10j+2 10j+3 10j+4 10j+5'); WriteLn(' 10j+6 10j+7 10j+8 10j+9'); for i := 0 to 19 do begin Write((j+i):6, ' '); TextColor(14); TextBackground(1); for h := 0 to 9 do begin p := pwr[10*i + h]; if (b = p) or (p = 1) then begin TextColor(15); Write(p:7:0); TextColor(14) end else Write(p:7:0) end; Write(' '); TextColor(15); TextBackground(0) end; TextBackground(7); GoToXY(1, 25); ClrEoL; if j > 0 then TextColor(4) else TextColor(15); Write(' PgUp'); if j < MaxJ then TextColor(4) else TextColor(15); Write(' PgDn'); TextColor(4); Write(' B'); TextColor(0); Write('ase '); TextColor(4); Write('E'); TextColor(0); Write('xponent '); TextColor(4); Write('M'); TextColor(0); Write('odulus '); TextColor(4); Write('P'); TextColor(0); Write('rint '); TextColor(4); Write('Esc'); GoToXY(1, 25); {hide the cursor} TextColor(7); Write(' '); GoToXY(1, 25); TextColor(0) end; {of procedure Display} procedure PrinTab; {PRINT powers up to PrinterLimit lines} var p {powers to be entered in table} : comp; St : string[12]; h, i, ind, {indices} l {length of string} : integer; begin ClrEoL; Write(' Printing table . . . '); Str(a:1:0, St); l := Length(St); Str(m:1:0, St); l := l + length(St); ind := (63 - l) div 2; {amount to indent by, to center title} WriteLn(lst); for i := 1 to ind do Write(Lst, ' '); WriteLn(Lst, 'POWERS OF ', a:1:0, ' (MOD ', m:1:0, ')'); WriteLn(Lst); Write(Lst, ' j 10j 10j+1 10j+2 10j+3 10j+4 10j+5'); WriteLn(Lst, ' 10j+6 10j+7 10j+8 10j+9'); WriteLn(Lst); p := 1; for i := 0 to PrinterLimit - 1 do begin Write(Lst, i:6); Write(Lst, ' '); for h := 0 to 9 do begin Write(Lst, p:7:0); p := condition(b*p, m) end; WriteLn(Lst) end; WriteLn(Lst) end; {of procedure PrinTab} begin {main body} OriginalMode := LastMode; Ch := 'F'; FuncKey := False; TextColor(14); TextBackground(1); ClrScr; GoToXY(30, 10); WriteLn('POWERS OF a (mod m)'); WriteLn; a := GetInput(1, WhereY, ' Enter a = ', ' (³a³ ó 999999)', -MaxMod, MaxMod); m := GetInput(WhereX, WhereY, ' Enter m = ', ' (0 < m ó 999999)', 1, MaxMod); b := condition(a, m); repeat if Ch = 'F' then begin pwr[0] := 1; j := 0 end; if (not FuncKey) and (UpCase(Ch) = 'B') then begin a := GetInput(1, 24, ' Enter new base a = ', ' (|a| ó 999999)', -MaxMod, MaxMod); b := condition(a, m); pwr[0] := power(b, 10*j, m) end; if (not FuncKey) and (UpCase(Ch) = 'E') then begin k := round(GetInput(1, 24, ' Enter new exponent k = ', ' (0 ó k ó 999999)', 0, MaxMod)); j := k div 10; if j > MaxJ then j := MaxJ; pwr[0] := power(b, 10*j, m); end; if (not FuncKey) and (UpCase(Ch) = 'M') then begin m := GetInput(1, 24, ' Enter new modulus m = ', ' (0 < m ó 999999)', 1, MaxMod); b := condition(a, m); pwr[0] := power(b, 10*j, m) end; if (FuncKey) and (Ch = #73) {PgUp} then begin j := j - 20; if j < 0 then j := 0; pwr[0] := power(b, 10*j, m) end; if (FuncKey) and (Ch = #81) {PgDn} then begin j := j + 20; pwr[0] := condition(pwr[199]*b, m) end; {First entry of table has been calculated-- now complete rest of table} for i := 1 to 199 do pwr[i] := condition(pwr[i-1]*b, m); if (not FuncKey) and (UpCase(Ch) = 'P') then PrinTab; Display(j); repeat Ch := ReadKey; if Ch <> #0 then FuncKey := False else begin FuncKey := True; Ch := ReadKey end; InputOk := False; if FuncKey and (Ch = #73) and (j > 0) then InputOk := True; if FuncKey and (Ch = #81) and (j < MaxJ) then InputOk := True; if (not FuncKey) and (Ch in [#27,'b', 'B', 'e', 'E', 'm', 'M', 'p', 'P']) then InputOk := True; until InputOk; Until (not funckey) and (ch = #27); TextMode(OriginalMode) end.