program MagicSquare; const MaxSquare = 15; type SquareRange = 1..MaxSquare; MagEltType = Integer; {must be a type with addition} MagSqType = array[SquareRange,SquareRange] of MagEltType; var MagSq : MagSqType; SqSize, J : SquareRange; Sum : MagEltType; {the sum of the first row} Magic : Boolean; procedure ReadMagSq(FSqSize : SquareRange; var FMS : MagSqType); {pre: FSqSize the array size; post: FMS contains FSqSize by FSqSize array} var I,J : SquareRange; begin WriteLn('Type in ',FSqSize : 2,' rows of ',FSqSize,' integers'); for I := 1 to FSqSize do begin for J := 1 to FSqSize do Read( FMS[I,J] ); ReadLn; end;{for I} WriteLn; end;{ReadMagSq} procedure WriteSq(FSqSize : SquareRange; var FMS : MagSqType; FM : Boolean); {pre: FSqSize the array size; FM true if a Magic Square post: the array written with a message} var I,J : SquareRange; begin if FM then WriteLn('The square below is a Latin square') else WriteLn('The square below is not a Latin square'); WriteLn; WriteLn; for I := 1 to FSqSize do begin for J := 1 to FSqSize do Write( FMS[I,J] : 3); WriteLn; end;{for I} end;{ReadMagSq} procedure CheckRows( FSum : MagEltType; FSqSize : SquareRange; FMS : MagSqType; var FM : Boolean); {pre: FM true; FSum has value; MagSqType has values post: FM true only if all rows sum to FSum} var RowSum : MagEltType; I,J : SquareRange; begin I := 2; while (I <= FSqSize) and FM do begin RowSum := 0; for J := 1 to FSqSize do RowSum := RowSum + FMS[I,J]; FM := RowSum = FSum; I := I + 1 end;{while} end;{Checkrows} procedure CheckCols( FSum : MagEltType; FSqSize : SquareRange; FMS : MagSqType; var FM : Boolean); {pre: FM true; FSum has value; MagSqType has values post: FM true only if all cols sum to FSum} var ColSum : MagEltType; I,J : SquareRange; begin J := 1; while (J <= FSqSize) and FM do begin ColSum := 0; for I := 1 to FSqSize do ColSum := ColSum + FMS[I,J]; FM := ColSum = FSum; J := J + 1 end;{while} end;{CheckCols} procedure CheckDiags( FSum : MagEltType; FSqSize : SquareRange; FMS : MagSqType; var FM : Boolean); {pre: FM true; Sum has value; MagSqType has values post: FM true only if both diagonals sum to FSum} var DiagSum : Integer; I : SquareRange; begin DiagSum := 0; for I := 1 to FSqSize do DiagSum := DiagSum + FMS[I,I]; FM := DiagSum = FSum; if FM then begin DiagSum := 0; for I := 1 to FSqSize do DiagSum := DiagSum + FMS[FSqSize + 1 - I,I]; FM := DiagSum = FSum; end;{if FM} end;{Checkdiags} begin{main} Write('Input square size ( <',MaxSquare:2,') >'); ReadLn(SqSize); ReadMagSq(SqSize,MagSq); Sum := 0; for J := 1 to SqSize do Sum := Sum + MagSq[1,J]; Magic := True; CheckRows(Sum,SqSize,MagSq,Magic); if Magic then CheckCols(Sum,SqSize,MagSq,Magic); if Magic then CheckDiags(Sum,SqSize,MagSq,Magic); WriteSq(SqSize,MagSq,Magic) end.{main}