← DL-Pascal collection

cov10.pas

DOWNLOAD ORIGINAL FILE

{ DL-Pascal Coverage Section 10: Units                 }
{ Exercises USES, unit constants/types/vars,           }
{ exported procedures and functions, unit-level state, }
{ private implementation, unit initialization.         }
{ Requires: MATHTOOL.INT compiled to MATHTOOL.UNI      }
{           MATHTOOL.PAS compiled to MATHTOOL.OLE      }
{ Expected: runs without error, displays results.      }
{$D-C-R-}

PROGRAM Section10;

USES MathTool;

VAR
  i, j    : Integer;
  li      : LongInt;
  r       : Real;
  b       : Boolean;
  st      : TStats;

PROCEDURE Check(msg : STRING; passed : Boolean);
BEGIN
  IF passed THEN
    WriteLn('OK   ', msg)
  ELSE
    WriteLn('FAIL ', msg);
END;

{ ---- Unit constants and types ---- }
PROCEDURE TestUnitConst;
BEGIN
  Check('UT_VERSION',    UT_VERSION = 10);
  Check('UT_PI approx',  (UT_PI > 3.14159) AND (UT_PI < 3.14160));
  WriteLn('  UT_PI = ', UT_PI:12:10);
END;

{ ---- Basic arithmetic functions ---- }
PROCEDURE TestArith;
BEGIN
  Check('UTAdd 3+4',     UTAdd(3, 4) = 7);
  Check('UTAdd neg',     UTAdd(-5, 3) = -2);
  Check('UTAdd zero',    UTAdd(0, 0) = 0);

  li := UTMul(1000, 1000);
  Check('UTMul 1M',      li = 1000000);
  li := UTMul(-100, 200);
  Check('UTMul neg',     li = -20000);

  Check('UTMax 3 7',     UTMax(3, 7) = 7);
  Check('UTMax 7 3',     UTMax(7, 3) = 7);
  Check('UTMax equal',   UTMax(5, 5) = 5);

  Check('UTMin 3 7',     UTMin(3, 7) = 3);
  Check('UTMin 7 3',     UTMin(7, 3) = 3);

  Check('UTAbs neg',     UTAbs(-9) = 9);
  Check('UTAbs pos',     UTAbs(9)  = 9);
  Check('UTAbs zero',    UTAbs(0)  = 0);
END;

{ ---- Prime testing ---- }
PROCEDURE TestPrime;
BEGIN
  Check('Prime 2',       UTIsPrime(2));
  Check('Prime 3',       UTIsPrime(3));
  Check('Prime 5',       UTIsPrime(5));
  Check('Prime 7',       UTIsPrime(7));
  Check('Prime 11',      UTIsPrime(11));
  Check('Prime 13',      UTIsPrime(13));
  Check('Prime 97',      UTIsPrime(97));
  Check('Not prime 1',   NOT UTIsPrime(1));
  Check('Not prime 4',   NOT UTIsPrime(4));
  Check('Not prime 9',   NOT UTIsPrime(9));
  Check('Not prime 100', NOT UTIsPrime(100));

  { Count primes up to 20 }
  j := 0;
  FOR i := 2 TO 20 DO
    IF UTIsPrime(i) THEN Inc(j);
  Check('Primes 2..20',  j = 8);  { 2,3,5,7,11,13,17,19 }
END;

{ ---- Factorial ---- }
PROCEDURE TestFactorial;
BEGIN
  Check('Fact 0',        UTFactorial(0) = 1);
  Check('Fact 1',        UTFactorial(1) = 1);
  Check('Fact 5',        UTFactorial(5) = 120);
  Check('Fact 10',       UTFactorial(10) = 3628800);
  li := UTFactorial(12);
  Check('Fact 12',       li = 479001600);
END;

{ ---- GCD ---- }
PROCEDURE TestGcd;
BEGIN
  Check('GCD 12 8',      UTGcd(12, 8)   = 4);
  Check('GCD 100 75',    UTGcd(100, 75) = 25);
  Check('GCD prime',     UTGcd(17, 13)  = 1);
  Check('GCD same',      UTGcd(7, 7)    = 7);
  Check('GCD one',       UTGcd(5, 1)    = 1);
END;

{ ---- Statistics ---- }
PROCEDURE TestStats;
BEGIN
  UTInitStats(st);
  Check('Stats init count', st.count = 0);
  Check('Stats init sum',   st.sum   = 0);

  FOR i := 1 TO 10 DO UTAddStat(st, i);

  Check('Stats count',   st.count = 10);
  Check('Stats sum',     st.sum   = 55);
  Check('Stats min',     st.min   = 1);
  Check('Stats max',     st.max   = 10);

  r := UTMean(st);
  Check('Stats mean',    (r > 5.49) AND (r < 5.51));

  { Reset and test with negatives }
  UTInitStats(st);
  UTAddStat(st, -5);
  UTAddStat(st, 0);
  UTAddStat(st, 5);
  Check('Stats neg min', st.min = -5);
  Check('Stats neg max', st.max = 5);
  Check('Stats neg sum', st.sum = 0);
  r := UTMean(st);
  Check('Stats neg mean',r = 0.0);
END;

{ ---- Unit-level variable (CallCount) ---- }
PROCEDURE TestUnitVar;
VAR before : Integer;
BEGIN
  UTReset;
  Check('CallCount 0',   CallCount = 0);

  before := CallCount;
  i := UTAdd(1, 2);
  Check('CallCount+1',   CallCount = before + 1);

  before := CallCount;
  i := UTMax(1, 2);
  i := UTMin(1, 2);
  i := UTAbs(-5);
  Check('CallCount+3',   CallCount = before + 3);

  UTReset;
  Check('Reset to 0',    CallCount = 0);
END;

{ ---- Compose unit functions ---- }
PROCEDURE TestCompose;
VAR
  primes : ARRAY[1..10] OF Integer;
  np     : Integer;
BEGIN
  { Find first 10 primes using unit }
  np := 0; i := 2;
  WHILE np < 10 DO BEGIN
    IF UTIsPrime(i) THEN BEGIN
      Inc(np);
      primes[np] := i;
    END;
    Inc(i);
  END;
  Check('10th prime',    primes[10] = 29);
  Check('1st prime',     primes[1]  = 2);
  Check('5th prime',     primes[5]  = 11);

  { GCD of factorial results }
  li := UTGcd(UTFactorial(4), UTFactorial(6));
  Check('GCD fact',      li = 24);  { GCD(24, 720) = 24 }

  { Sum of primes up to 50 using stats }
  UTInitStats(st);
  FOR i := 2 TO 50 DO
    IF UTIsPrime(i) THEN UTAddStat(st, i);
  Check('Primes to 50',  st.count = 15);
  Check('Sum primes 50', st.sum = 328);  { 2+3+5+7+11+13+17+19+23+29+31+37+41+43+47 }

  { Nested calls }
  i := UTMax(UTAdd(3, 4), UTMul(2, 3));
  Check('Nested calls',  i = 7);  { max(7, 6) }
END;

{ ---- Unit initialization was called ---- }
PROCEDURE TestInit;
BEGIN
  { CallCount was 0 at start (set by unit initialization) }
  UTReset;
  Check('Unit init',     CallCount = 0);
  WriteLn('  Unit MathTools version: ', UT_VERSION);
END;

{ ---- Main ---- }
BEGIN
  WriteLn('=== Section 10: Units ===');
  WriteLn;

  WriteLn('-- Unit Constants --');
  TestUnitConst;    WriteLn;

  WriteLn('-- Arithmetic --');
  TestArith;        WriteLn;

  WriteLn('-- Prime --');
  TestPrime;        WriteLn;

  WriteLn('-- Factorial --');
  TestFactorial;    WriteLn;

  WriteLn('-- GCD --');
  TestGcd;          WriteLn;

  WriteLn('-- Statistics --');
  TestStats;        WriteLn;

  WriteLn('-- Unit Variable --');
  TestUnitVar;      WriteLn;

  WriteLn('-- Compose --');
  TestCompose;      WriteLn;

  WriteLn('-- Initialization --');
  TestInit;         WriteLn;

  WriteLn('=== Section 10 complete ===');
END.