Which of 3 matrixes has the biggest element number sum (FreePacal)? - pascal

I have a program which outputs 3 (4x4) matrixes (different number, same layout)
And I must output again matrix, which element number sum are the biggest.
For example 65 is the most biggest elements number sum.
1 2 3 4 10 1 2 3 4 10 1 1 1 1 4
5 6 7 8 26 2 3 4 5 14 2 2 2 2 8
9 1 2 3 15 3 4 5 6 18 3 3 3 3 12
2 3 4 5 14 4 5 6 7 22 4 4 4 4 16
65 64 40
The program which generates 3 random matrixes:
uses
SysUtils;
var
i: integer;
x: integer;
y: integer;
matrix: array[1..4, 1..4] of integer;
begin
randomize;
for i := 1 to 3 do
begin
for x := 1 to 4 do
for y := 1 to 4 do
matrix[x, y] := random(101);
for x := 1 to 4 do
begin
for y := 1 to 4 do
write(IntToStr(matrix[x, y]), ' ');
writeln;
end;
writeln;
end;
readln;
end.
Can You help me? I would be very thankful.

Could be this way for instance:
program Project1;
uses
SysUtils;
// create a type for the matrix
type
TMatrix = array[1..4, 1..4] of Integer;
var
I: Integer;
X: Integer;
Y: Integer;
CurSum: Integer;
MaxIdx: Integer;
MaxSum: Integer;
Matrices: array[1..3] of TMatrix;
begin
// initialize random seed
Randomize;
// initialize max. sum matrix index and max. matrix sum
MaxIdx := 0;
MaxSum := 0;
// iterate to create 3 matrices
for I := 1 to 3 do
begin
// initialize sum value of this matrix to 0
CurSum := 0;
// iterate to fill the matrices with random values
for X := 1 to 4 do
for Y := 1 to 4 do
begin
// to the matrix I assign a random value to the X, Y position
Matrices[I][X, Y] := Random(101);
// add this random value to the current matrix sum value
CurSum := CurSum + Matrices[I][X, Y];
end;
// check if this matrix sum value is greater than the stored one
// and if so, then...
if CurSum > MaxSum then
begin
// store this matrix index
MaxIdx := I;
// and store this matrix sum as a max sum value
MaxSum := CurSum;
end;
// print out this matrix
for X := 1 to 4 do
begin
for Y := 1 to 4 do
Write(IntToStr(Matrices[I][X, Y]), ' ');
WriteLn;
end;
WriteLn;
end;
// print out the index of the matrix with max sum and its sum value
WriteLn;
WriteLn('The biggest matrix is the ' + IntToStr(MaxIdx) + '. one. The sum ' +
'of this matrix is ' + IntToStr(MaxSum) + '.');
WriteLn;
// and print out that matrix with max sum value
for X := 1 to 4 do
begin
for Y := 1 to 4 do
Write(IntToStr(Matrices[MaxIdx][X, Y]), ' ');
WriteLn;
end;
ReadLn;
end.

Related

Pascal print numbers alternately

I have a task to print each number from the input alternately, firstly numbers with even indexes, then numbers with odd indexes. I have solved it, but only for one line of numbers, but I have to read n lines of numbers.
Expected input:
2
3 5 7 2
4 2 1 4 3
Expected output:
7 5 2
1 3 2 4
Where 2 is number of lines, 3 and 4 are numbers of numbers, 5, 7, 2 and 2, 1 , 4, 3 are these numbers.
Program numbers;
Uses crt;
var k,n,x,i,j: integer;
var tab : Array[1..1000] of integer;
var tab1 : Array[1..1000] of integer;
var tab2 : Array[1..1000] of integer;
begin
clrscr;
readln(k);
for i:=1 to k do
begin
read(n);
for j:=1 to n do
begin
read(tab[j]);
if(j mod 2 = 0) then
tab1[j]:=tab[j]
else
begin
tab2[j]:=tab[j];
end;
end;
end;
for j:=1 to n do
if tab1[j]<>0 then write(tab1[j], ' ');
for j:=1 to n do
if tab2[j]<>0 then write(tab2[j], ' ');
end.
Let's clean up the formatting, and use a record to keep track of each "line" of input.
program numbers;
uses
crt;
type
TLine = record
count : integer;
numbers : array[1..1000] of integer
end;
var
numLines, i, j : integer;
lines : Array[1..1000] of TLine;
begin
clrscr;
readln(numLines);
for i := 1 to numLines do
begin
read(lines[i].count);
for j := 1 to lines[i].count do
read(lines[i].numbers[j])
end
end.
We can read each line in. Now, how do we print the odd and even indices together? Well, we could do math on each index, or we could just increment by 2 instead of 1 using a while loop.
program numbers;
uses
crt;
type
TLine = record
count : integer;
numbers : array[1..1000] of integer
end;
var
numLines, i, j : integer;
lines : Array[1..1000] of TLine;
begin
clrscr;
readln(numLines);
// Read in lines.
for i := 1 to numLines do
begin
read(lines[i].count);
for j := 1 to lines[i].count do
read(lines[i].numbers[j])
end;
// Print out lines.
for i := 1 to numLines do
begin
j := 1;
while j <= lines[i].count do
begin
write(lines[i].numbers[j], ' ');
j := j + 2
end;
j := 2;
while j <= lines[i].count do
begin
write(lines[i].numbers[j], ' ');
j := j + 2
end;
writeln
end
end.
Now if we run this:
2
3 4 5 6
4 6 2 4 1
4 6 5
6 4 2 1
One thing we can note is that the following loop is the same for both odd and even indexes, except for the start index.
while j <= lines[i].count do
begin
write(lines[i].numbers[j], ' ');
j := j + 2
end;
This is a perfect place to use a procedure. Let's call it PrintEveryOther and have it take an index to start from and a line to print.
program numbers;
uses
crt;
type
TLine = record
count : integer;
numbers : array[1..1000] of integer
end;
var
numLines, i, j : integer;
lines : Array[1..1000] of TLine;
procedure PrintEveryOther(start : integer; line :TLine);
var
i : integer;
begin
i := start;
while i <= line.count do
begin
write(line.numbers[i], ' ');
i := i + 2
end
end;
begin
clrscr;
readln(numLines);
for i := 1 to numLines do
begin
read(lines[i].count);
for j := 1 to lines[i].count do
read(lines[i].numbers[j])
end;
for i := 1 to numLines do
begin
PrintEveryOther(1, lines[i]);
PrintEveryOther(2, lines[i]);
writeln
end
end.

Pascal - Sum of odd numbers between 0 and X

I've beeng having some trouble with this code... I need to create an algorithm which makes the user input a number (X), and then the program calculates the sum of all the odd numbers below (x).
This what I've tried so far, but can't really wrap my head around the logic behind it:
Program odd_numbers;
Var
Num, Limite, Soma: integer;
Begin;
Soma := 0;
Writeln('Choose a limit:');
Readln(Limite);
While (Limite / 2 > 0) do
Begin;
Soma := ((Num < Limite) mod 2 > 0);
Writeln('The sum of odd numbers from 0 to ', Limite, ' é ', Soma);
End;
if (Limite mod 2 = 0) then
Begin;
Soma := ((Num < Limite) mod 2 = 0);
Writeln('The sum of odd numbers from 0 to ', Limite, ' é ', Soma);
End;
End.
*PS: Been writing the code with variables in Portuguese, so don't mind the variables appearing weird to understand. *
I see that everyone is happily looping, but this is not necessary. This is a simple arithmetic sequence, and the sum can be calculated without a loop.
Just think of the following:
1 + 3 = 2 * (1 + 3) / 2 = 2 * 2 = 4 ; limits 3 and 4
1 + 3 + 5 = 3 * (1 + 5) / 2 = 3 * 3 = 9 ; limits 5 and 6
1 + 3 + 5 + 7 = 4 * (1 + 7) / 2 = 4 * 4 = 16 ; limits 7 and 8
1 + 3 + 5 + 7 + 9 = 5 * (1 + 9) / 2 = 5 * 5 = 25 ; limits 9 and 10
1 + 3 + 5 + 7 + 9 + 11 = 6 * (1 + 11) / 2 = 6 * 6 = 36 ; limits 11 and 12
But not only that, you'll see that it is in fact always a perfect square: Sqr((n+1) div 2).
So just calculate:
program odd_numbers;
var
Num, Limite, Soma: Integer;
begin
Write('Choose a limit: ');
Readln(Limite);
Num := (Limite + 1) div 2;
Soma := Num * Num;
Writeln('The sum of odd numbers from 0 to ', Limite, ' is ', Soma);
end.
Looks a little simpler than what the others propose.
The loop While (Limite / 2 > 0) do ... uses real arithmetic and not integer arithmetic. I guess you mean While (Limite div 2 > 0) do ... And you should change Limite in the loop otherwise you get stuck because the exit condition can never be reached.
After you have asked the user to enter a number, Limite, you need to keep that unchanged, because you need it in the final message. You also need a loop where you go through all numbers from Limite towards 0.
You started with a while loop which is ok, you are just missing the loop control variable. That is a variable that eventually gets a terminating value which then stops the loop. Use for example the Num variable you already have declared. You can use the same variable to investigate the numbers between user input and 0, for being odd values.
num := limite-1; // give num a start value based on user input (-1 because of "... numbers below (x)")
while num > 0 do // stop the loop when 0 is reached
begin
// here you investigate if `num` is a odd number (e.g. using `mod` operator or
// possibly your pascal has a built in `function Odd(value: integer): boolean;`)
// and add it to `Soma` if it is
num := num - 1;// decrement num at every iteration
end;
Finally you need to consider changes to the above, to handle negative input from the user.
To test if an integer is an odd value, you could use following function:
function IsOdd( value : Integer) : Boolean;
begin
IsOdd := (value mod 2) <> 0;
end;
Many pascal compilers have a built-in function called Odd(), which you could use.
A while loop works well to solve this problem. If you start with lowest odd number above zero, i.e. one and continue upwards so long we do not exceed the limit value we have a simple start:
function GetOddSumBelowX( X : Integer) : Integer;
var
i,sum: Integer;
begin
i := 1; // Start with first odd number
sum := 0;
while (i < X) do begin // as long as i less than X, loop
if IsOdd(i) then begin
sum := sum + i; // add to sum
end;
i := i + 1; // Increment i
end;
GetOddSumBelowX := sum;
end;
Now, that was simple enough. Next step to simplify the loop is to increment the i variable by two instead, just to jump between all odd numbers:
function GetOddSumBelowX( X : Integer) : Integer;
var
i,sum: Integer;
begin
i := 1; // Start with first odd number
sum := 0;
while (i < X) do begin // as long as i less than X, loop
sum := sum + i; // add to sum
i := i + 2; // Increment to next odd number
end;
GetOddSumBelowX := sum;
end;

Divisibility of numbers in pascal

I want to write a pascal program that checks if particular number is divisible by 2, 3, 5, 7, 9 and 11 and whether the sum of the digits is even or odd. In the very end I want to write a statement like "This number is divisible by 5 and 9" and the sum of the numbers is even/odd. What should I do?
Use modulus:
program ModulusTest;
begin
if 8 mod 2 = 0 then
begin
write(8);
writeln(' is even');
end;
if 30 mod 5 = 0 then
begin
write(30);
writeln(' is divisible by 5');
end;
if 32 mod 5 <> 0 then
begin
write(32);
writeln(' is not divisible by 5');
end;
end.
Modulus is what remains after an integer division :)
This's my code, I separate into 2 sections :
program checkNumber;
var number : integer;
divider : string;
digit1, digit2, sum : integer;
begin
//First//
write('Number : '); readln(number);
if (number MOD 2 = 0) then divider := divider+'2, ';
if (number MOD 3 = 0) then divider := divider+'3, ';
if (number MOD 5 = 0) then divider := divider+'5, ';
if (number MOD 7 = 0) then divider := divider+'7, ';
if (number MOD 9 = 0) then divider := divider+'9, ';
if (number MOD 11 = 0) then divider := divider+'11, ';
write('This number is divisible by '); write(divider);
////////////////////////////////////////////////////////
//Second//
digit1 := number DIV 10;
digit2 := number MOD 10;
sum := digit1 + digit2;
write('and the sum of the numbers is ');
if (sum MOD 2 = 0) then write('even') else write('odd');
////////////////////////////////////////////////////////
end.
First part
You need MOD(modulus) operation to get the list of divider values:
write('Number : '); readln(number);
if (number MOD 2 = 0) then divider := divider+'2, ';
if (number MOD 3 = 0) then divider := divider+'3, '; //divider 2 3 5 7 9 11
.
.
Then save the divider into variable divider as string, and write it on monitor.
write('This number is divisible by '); write(divider);
Second part
You need to separate the digits into single variable using DIV(divide) and MOD(modulus) operation. In my code, I limit the number input for 2 digit (1 until 99):
digit1 := number DIV 10;
digit2 := number MOD 10;
sum := digit1 + digit2;
(You change the code use if..then.. function if you want input bigger number).
Then use MOD to check the number is even or odd:
if (sum MOD 2 = 0) then write('even') else write('odd');

Read symbols from from the text file?

10
Balta B 1 15
Melyna M 2 15
Zalia Z 3 12
Raduona R 4 10
Geltona G 5 10
Violetine V 6 12
Pilka P 7 10
Oranzine O 8 12
Alyvuogiu A 9 12
Juoda J 10 10
3 5
Andrius B 4 P 7 R 4 B 1 V 6
Tomas V 6 A 9 B 6 O 8 P 2
Evelina R 4 P 7 R 4 P 7 B 1
program Spalvotos_korteles;
type Spalvos = record
SPav : string[15]; // SpalvosPavadinimas
SNr, SSk : integer; // SpalvosNumeris, SpalvosSkaicius
SI : char; // SpalvuIndeksas
end;
Mokiniai = record
V : string[15]; // Mokinio vardas
MI : char; // Mokinio istrauktas indeksas
Mnr, TR, NR : integer; // Mokinio uzrasytas numeris TeisingiRasymai, NeteisingiRasymai
end;
Mas = array[1..100] of Spalvos;
Mas1 = array[1..100] of Mokiniai;
Mas2 = array[1..100] of char;
Mas3 = array[1..100] of integer;
var n, Q, MokSk, MokT : integer;
S : Mas;
M : Mas1;
VI : Mas2; // Visi Indeksai
VNr, Istraukta, TeisingiRasymai, Nepanaudota : Mas3; // VNr - Visi Numeriai
procedure Nuskaitymas;
var df : text;
Qq, i, j, z, ii : integer;
begin
Qq:=1;
assign(df,'duom.txt');
reset(df);
readln(df, n);
for i:= 1 to n do
readln(df, S[i].SPav, S[i].SI, S[i].SNr, S[i].SSk);
readln(df, MokSk, MokT);
for j := 1 to MokSk do
begin
read(df,M[j].V);
for z := 1 to MokT do
begin
read(df, M[z].MI, M[z].Mnr);
VI[Qq] := M[z].MI;
VNr[Qq] := M[z].Mnr;
Qq:=Qq+1;
for ii := 1 to n do
if (M[z].MI = S[ii].SI) and (M[z].Mnr = S[ii].SNr) then M[j].TR := M[j].TR+1;
end;
end;
Q:=Qq-1;
close(df);
end;
procedure Uzrasymai_ant_korteliu;
var i, j : integer;
begin
for i:= 1 to n do
begin
for j:= 1 to Q do
begin
if S[i].SI = VI[j] then
Istraukta[i]:=Istraukta[i]+1;
if (S[i].SI = VI[j]) and (S[i].SNr = VNr[j]) then
TeisingiRasymai[i]:= TeisingiRasymai[i]+1;
end;
Nepanaudota[i]:= S[i].SSk - Istraukta[i];
end;
end;
procedure Rezultatas;
var i, j : integer;
Rf : text;
begin
assign(rf,'SpalvuRezultas.Txt');
rewrite(rf);
for i := 1 to MokSk do
writeln(rf,M[i].V, M[i].TR);
writeln(rf);
for j := 1 to n do
writeln(rf,S[j].SPav, Istraukta[j], TeisingiRasymai[j], Nepanaudota[j]);
close(rf);
end;
begin
Nuskaitymas;
Uzrasymai_ant_korteliu;
Rezultatas;
end.
My goal is to read the 3 last roads and look how many numbers by the symbols are correct (the correct ones are symbol & first number from the columns) but when I try to read then I get the 106error wrong numeric format. I somehow understand that the problem because of the char symbols but I have no clue how to fix it. Could someone help me?
The main idea is to find out how the program interprets your read statement in your program.
Let ch, ch1, ch2 ... be a char and int, int1, int2 ... be an integer.
INPUT:
P 1 C 2
execute read(ch, int)
RESULT:
ch = P
int = 1
It works perfectly ok.
Let's expand this to read four elements.
INPUT:
P 1 C 2
execute read(ch1, int1, ch2, int2)
RESULT:
ch1 = P
int1 = 1
ch2 = C
int2 = 2
However,
INPUT:
P 1 C 2
execute read(ch1, int1); read(ch2, int2);
RESULT:
ch1 = P
int1 = 1
ERROR 106 when execute read(ch2, int2);
Why?
Let's see the following illustration.
reading ch1
1234567
P 1 C 2
^
The first read(ch1, int1) asks the program to read a char and then a integer, separated by SPACE. The program first read a char and move the pointer to position 2 and then knows it is a SPACE so move on read the next int which move the pointer to position 3.
reading int1
1234567
P 1 C 2
^
So it reads 1 into int1. And move the pointer to the next position. Then the first read is finished.
1234567
P 1 C 2
^
What's going on? Second read will read the char on position 4 which is a SPACE. It won't give out any warning as it is really a character. After that the position of pointer should be on position 5.
1234567
P 1 C 2
^
The program will not skip position 5 as it is not a SPACE. Therefore, 'C' is read into int2. As 'C' is not an integer, the program gives out a RUNTIME ERROR 106.
It seems that readln(df, S[i].SPav, S[i].SI, S[i].SNr, S[i].SSk); and read(df,M[j].V);read(df, M[z].MI, M[z].Mnr); have the same logic, but in the execution, they do not.
Moreover, you have to go to the next line after you have read all elements on a row by readln(df);.
FYI, below is the edited code:
program post;
type
Spalvos = record
SPav: string[15]; // SpalvosPavadinimas
SNr, SSk: integer; // SpalvosNumeris, SpalvosSkaicius
SI: char; // SpalvuIndeksas
end;
Mokiniai = record
V: string[15]; // Mokinio vardas
MI: char; // Mokinio istrauktas indeksas
Mnr, TR, NR: integer;
// Mokinio uzrasytas numeris TeisingiRasymai, NeteisingiRasymai
end;
Mas = array[1..100] of Spalvos;
Mas1 = array[1..100] of Mokiniai;
Mas2 = array[1..100] of char;
Mas3 = array[1..100] of integer;
var
n, Q, MokSk, MokT: integer;
S: Mas;
M: Mas1;
VI: Mas2; // Visi Indeksai
VNr, Istraukta, TeisingiRasymai, Nepanaudota: Mas3; // VNr - Visi Numeriai
temp: char;
procedure Nuskaitymas;
var
df: Text;
Qq, i, j, z, ii: integer;
begin
Qq := 1;
Assign(df, 'duom.txt');
reset(df);
readln(df, n);
for i := 1 to n do
readln(df, S[i].SPav, S[i].SI, S[i].SNr, S[i].SSk);
readln(df, MokSk, MokT);
for j := 1 to MokSk do
begin
Read(df, M[j].V);
for z := 1 to MokT do
begin
Read(df, M[z].MI, M[z].Mnr, temp);
writeln(M[z].MI, M[z].Mnr);
VI[Qq] := M[z].MI;
VNr[Qq] := M[z].Mnr;
Qq := Qq + 1;
for ii := 1 to n do
if (M[z].MI = S[ii].SI) and (M[z].Mnr = S[ii].SNr) then
M[j].TR := M[j].TR + 1;
end;
readln(df);
end;
Q := Qq - 1;
Close(df);
end;
procedure Uzrasymai_ant_korteliu;
var
i, j: integer;
begin
for i := 1 to n do
begin
for j := 1 to Q do
begin
if S[i].SI = VI[j] then
Istraukta[i] := Istraukta[i] + 1;
if (S[i].SI = VI[j]) and (S[i].SNr = VNr[j]) then
TeisingiRasymai[i] := TeisingiRasymai[i] + 1;
end;
Nepanaudota[i] := S[i].SSk - Istraukta[i];
end;
end;
procedure Rezultatas;
var
i, j: integer;
Rf: Text;
begin
Assign(rf, 'SpalvuRezultas.Txt');
rewrite(rf);
for i := 1 to MokSk do
writeln(rf, M[i].V, M[i].TR);
writeln(rf);
for j := 1 to n do
writeln(rf, S[j].SPav, Istraukta[j], TeisingiRasymai[j], Nepanaudota[j]);
Close(rf);
end;
begin
Nuskaitymas;
Uzrasymai_ant_korteliu;
Rezultatas;
end.
Thank you for your answer, but I already found out about char reading spaces too and I fixed it. Don't know if it is the best way but it works.
readln(df, MokSk, MokT);
for j := 1 to MokSk do
begin
read(df,M[j].V);
for z := 1 to MokT-1 do
begin
read(df, MI, Mnr, Tuscias); // M[z].MI P M[z].Mnr O
VI[Qq] := MI;
VNr[Qq] := Mnr;
Qq:=Qq+1;
for ii := 1 to n do
if (MI = S[ii].SI) and (Mnr = S[ii].SNr) then M[j].TR := M[j].TR+1;
end;
read(df, MI, Mnr);
VI[Qq] := MI;
VNr[Qq] := Mnr;
Qq:=Qq+1;
for ii := 1 to n do
if (MI = S[ii].SI) and (Mnr = S[ii].SNr) then M[j].TR := M[j].TR+1;
readln(df);
end;
Andrius B 4 P 7 R 4 B 1 V 6
Tomas V 6 A 9 B 6 O 8 P 2
Evelina R 4 P 7 R 4 P 7 B 1
I don't know any other way to read this program, so I made it like this.
P.s. I tried your way before but it didn't work because after the last pair there's no space and the program makes an error out of it. But thanks for your help kind sir :)

Magic Square FreePascal

Program must output whether the square is magic square or not.
I must read square from file.
Magic square - all rows, all columns and both diagonals sum must be equal.
Program shows right answer, but these 16 numbers must be read from text file.
Text file is looking like:
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
Program itself:
var
m:array[1..4,1..4] of integer;
i:byte;
j:byte;
r1,r2,r3,r4,c1,c2,c3,c4,d1,d2:integer;
begin
for i:=1 to 4 do
for j:=1 to 4 do
begin
write('Enter value for column=',i,' row=',j,' :');
readln(m[i,j]);
end;
r1:=m[1,1]+m[1,2]+m[1,3]+m[1,4];
r2:=m[2,1]+m[2,2]+m[2,3]+m[2,4];
r3:=m[3,1]+m[3,2]+m[3,3]+m[3,4];
r4:=m[4,1]+m[4,2]+m[4,3]+m[4,4];
c1:=m[1,1]+m[2,1]+m[3,1]+m[4,1];
c2:=m[1,2]+m[2,2]+m[3,2]+m[4,2];
c3:=m[1,3]+m[2,3]+m[3,3]+m[4,3];
c4:=m[1,4]+m[2,4]+m[3,4]+m[4,4];
d1:=m[1,1]+m[2,2]+m[3,3]+m[4,4];
d2:=m[1,4]+m[2,3]+m[3,2]+m[4,1];
if (r1=r2) and (r2=r3) and (r3=r4) and (r4=c1) and (c1=c2) and (c2=c3) and (c3=c4) and (c4=d1) and (d1=d2) then
begin
write('Magic Square');
end
else
begin
write('Not Magic Square');
end;
readln;
end.
Here is a procedure to read the matrix from a text file.
The row elements are supposed to be separated with space.
type
TMatrix = array[1..4,1..4] of integer;
procedure ReadMatrix( const filename: String; var M: TMatrix);
var
i,j : integer;
aFile,aLine : TStringList;
begin
aFile := TStringList.Create;
aLine := TStringList.Create;
aLine.Delimiter := ' ';
try
aFile.LoadFromFile(filename);
Assert(aFile.Count = 4,'Not 4 rows in TMatrix');
for i := 0 to 3 do
begin
aLine.DelimitedText := aFile[i];
Assert(aLine.Count = 4,'Not 4 columns in TMatrix');
for j := 0 to 3 do
M[i+1,j+1] := StrToInt(aLine[j]);
end;
finally
aLine.Free;
aFile.Free;
end;
end;

Resources