Convert real to Integer in loop in Pascal - for-loop

I'm new in Pascal and I don't know how a fix this error:
Incompatible types: got "S80REAL" expected "LONGINT"
My code is:
Var
number1:Integer;
a,b:Integer;
a,i:Integer;
procedure number(number1: Integer);
begin
a:=1;
b:=number1+(number1-1);
for a:=1 to number1 do
begin
for i:=1 to ((b-a)/2) do
begin
write('#');
end;
end;
end;
Error is here: for i:=1 to ((b-a)/2) do
Thank you for help.

Replace the '/' ( (b-a)/2 ) with 'div'
'/' is real division in Pascal, 'div' is integer division
procedure number(number1: Integer);
begin
a:=1;
b:=number1 + number1 - 1;
for a:=1 to number1 do
begin
for i:=1 to ((b-a) div 2) do
begin
write('#');
end;
end;
end;

Related

What is an exit code 201 in Free Pascal?

I have tried to make a simple snake game with Free Pascal, when I started the programme, it drew the map exactly what I want but after that, I pressed the button that I have set to control the snake and it exited with exit code 201.
I don't know much about that exit code, could you explain me the problems of the programme? This is the longest program I have ever made with Pascal.
Here is the code:
uses crt;
type
ran=record
x:byte;
y:byte;
end;
var
f:ran;
s:array[1..1000] of ran;
i,j:longint;
st,l:byte;
function getkey:integer;
var
k:integer;
begin
k:=ord(readkey);
if k=0 then k:=-ord(readkey);
getkey:=k;
end;
procedure fa;
begin
randomize;
f.x:=random(98)+1;
f.y:=random(23)+1;
gotoxy(f.x,f.y);
writeln('o');
end;
procedure draw;
begin
gotoxy(1,1);
st:=1;
for i:=1 to 25 do begin
for j:=1 to 100 do write('X');
writeln
end;
gotoxy(st+1,st+1);
for i:=1 to 23 do begin
for j:=1 to 98 do write(' ');
gotoxy(st+1,i+2);
end;
end;
procedure sts;
begin
s[1].x:=19;
s[1].y:=6;
gotoxy(s[1].x,s[1].y);
writeln('#');
end;
procedure fa1;
begin
f.x:=29;
f.y:=5;
gotoxy(f.x,f.y);
writeln('o');
end;
procedure eat;
begin
if (s[1].x=f.x) and (s[1].y=f.y) then begin
l:=l+1;
fa;
end;
end;
function die:boolean;
begin
die:=false;
if (s[1].x=1) or (s[1].x=100) or (s[1].y=1) or (s[1].y=25) then
die:=true;
if l>=5 then
for i:=5 to l do
if (s[1].x=s[i].x) and (s[1].y=s[i].y) then
die:=true;
end;
procedure up;
begin
for i:=l downto 2 do begin
s[i].y:=s[i-1].y;
gotoxy(s[i].x,s[i].y);
writeln('+');
end;
gotoxy(s[l].x,s[l].y+1);
writeln(' ');
s[1].y:=s[1].y-1;
gotoxy(s[1].x,s[1].y);
writeln('#');
end;
procedure down;
begin
for i:=l downto 2 do begin
s[i].y:=s[i-1].y;
gotoxy(s[i].x,s[i].y);
writeln('+');
end;
gotoxy(s[l].x,s[l].y-1);
writeln(' ');
s[1].y:=s[1].y+1;
gotoxy(s[1].x,s[1].y);
writeln('#');
end;
procedure left;
begin
for i:=l downto 2 do begin
s[i].x:=s[i-1].x;
gotoxy(s[i].x,s[i].y);
writeln('+');
end;
gotoxy(s[l].x+1,s[l].y);
writeln(' ');
s[1].x:=s[1].x-1;
gotoxy(s[1].x,s[1].y);
writeln('#');
end;
procedure right;
begin
for i:=l downto 2 do begin
s[i].x:=s[i-1].x;
gotoxy(s[i].x,s[i].y);
writeln('+');
end;
gotoxy(s[l].x-1,s[l].y);
writeln(' ');
s[1].x:=s[1].x+1;
gotoxy(s[1].x,s[1].y);
writeln('#');
end;
procedure auto(k:integer);
begin
case k of
-72:up;
-80:down;
-75:left;
-77:right;
119:up;
115:down;
97:left;
100:right;
end;
end;
procedure ingame(t:integer);
var
d,e:boolean;
begin
repeat
auto(t);
d:=die;
if d=true then exit;
eat;
until (keypressed);
if keypressed then t:=getkey;
case t of
-72:up;
-80:down;
-75:left;
-77:right;
119:up;
115:down;
97:left;
100:right;
end;
eat;
d:=die;
if d=true then exit;
end;
procedure first;
var
k:integer;
begin
draw;
fa1;
sts;
if keypressed then k:=getkey;
ingame(k);
end;
BEGIN
clrscr;
first;
readln
END.
I googled this: 201 : range error, so you probably go out of array bounds. The only array s in indexed by variables that depend on l value (weird name, BTW). But I see a single place where you do changing (increment) this variable and don't see any l initialization. So you are using arbitrary starting value (here perhaps zero because l is global).
Note that you could discover this bug (and perhaps others) with simple debugging.
The code 201 seems to be explained for example here: Runtime Error 201 at fpc
Exactly why this happens in your code, I don't know.

Pascal Program toString not working

I am working on a Pascal program that works with sets without using the built in operations. However my toString function is not working and I cannot figure out why.
This is the main part of the program
unit isetADT; {// do not change this!}
interface
const
MAX_SIZE = 100; {// if needed, use value 100; arbitrary}
type
iset = record {// your type definition goes here}
arrayint:array[1..MAX_SIZE] of integer;
setsize:integer;
end;
procedure makeEmpty(var s:iset);
function isEmpty(s:iset):boolean;
function isMember(n:integer; s:iset):boolean;
function equals(s1,s2:iset):boolean;
function card(s:iset):integer; {// cardinality}
procedure add(n:integer; var s:iset); {// does nothing if n is already a member of s}
procedure remove(n:integer; var s:iset); {// does nothing if n is not in s}
procedure union(s1,s2:iset; var res:iset);
procedure intersect(s1,s2:iset; var res:iset);
procedure diff(s1,s2:iset; var res:iset); {// s1 - s2}
function toString(s:iset):ansistring;
implementation
{// your implementation code goes here}
procedure makeEmpty(var s:iset);
begin
{s:=[]; clears array, unneeded}
s.setsize:=0;
end;
function isEmpty(s:iset):boolean;
var
empty:boolean;
begin
empty:=false;
if s.setsize=0 then
empty:=true;
isEmpty:=empty;
end;
function isMember(n:integer; s:iset):boolean;
var
count:integer;
begin
member:=false;
if s.setsize>0 then
begin
for count:=1 to s.setsize do
begin
if s.arrayint[count]=n then
isMember:=true;
end;
end;
end;
function equals(s1,s2:iset):boolean;
var
equal:boolean;
count:integer;
begin
equal:=false;
if s1.setsize<>s2.setsize then
else
begin
for count:=1 to s1.setsize do
begin
if isMember(s1.arrayint[count],s2) then
equal:=true
else
equal:=false;
end;
end;
equals:=equal;
end;
function card(s:iset):integer; {// cardinality}
var
cardinality:integer;
begin
cardinality:=s.setsize;
end;
procedure add(n:integer; var s:iset);
begin
if isMember(n,s) then
{it is already in the set nothing is done}
else
begin
s.setsize:=s.setsize+1; {adds 1 to the size so that the new member can be added}
s.arrayint[s.setsize]:=n; {puts member in the newly created space}
end;
end;
procedure remove(n:integer; var s:iset);
var
newsize:integer;
count:integer;
count2:integer;
begin
{needed to keep size constant when it is being changed in nested loops}
newsize:=s.setsize;
if isMember(n,s) then
begin
for count:= 1 to newsize do
begin
if s.arrayint[count]=n then
begin
for count2:=1 to newsize do
begin
s.arrayint[count]:=s.arrayint[count+1]; {replaces the removed member}
end;
s.setsize:=s.setsize-1;{removes unneeded size}
end;
end;
end;
end;
procedure union(s1,s2:iset; var res:iset);
var
count:integer;
count2:integer;
begin
makeEmpty(res);
if equals(s1,s2) then
{they are the same, nothing is done}
else
begin
{takes a member of s2 and puts it res if it is not in s1 since res is the same as s1}
for count:=1 to s1.setsize do
begin
add(s1.arrayint[count],res);
end;
for count2:=1 to s2.setsize do
begin
add(s2.arrayint[count2],res);
end;
end;
end;
procedure intersect(s1,s2:iset; var res:iset);
var
count:integer;
begin
if equals(s1,s2) then
res:=s1 {since they are the same only 1 needs to be returned}
else
begin
for count:=1 to s1.setsize do
begin
{number is added to res if it is in both s1 AND s2 only}
if isMember(s1.arrayint[count],s2) then
add(s1.arrayint[count],res)
end;
end;
end;
procedure diff(s1,s2:iset; var res:iset);
var
member:boolean;
count:integer;
count2:integer;
begin
member:=false;
if equals(s1,s2) then
{if they are the same then nothing is returned because there is no difference}
makeEmpty(res)
else
begin
for count:=1 to s1.setsize do
begin
for count2:=1 to s2.setsize do
begin
{if number is in s1 and not s2 then it is true and it is added to res}
if s1.arrayint[count]=s2.arrayint[count2] then
member:=true;
end;
if member=false then
add(s1.arrayint[count],res);
end;
end;
end;
function toString(s:iset):ansistring; {this is just a string with no size limit}
var
print:ansistring;
x:string;
i: Integer;
count:integer;
begin
print:='';
for count:=1 to s.setsize do
begin
i:=s.arrayint[count];
str(i,x);
print:=print+x+',';
end;
print:='{'+ print+'}';
toString:=print;
end;
end. {END OF PROGRAM}
and this is the runner for the program
program testisetSample;
uses isetADT;
var
s1,s2,s3 : iset;
i : integer;
begin
makeEmpty(s1); makeEmpty(s2);
for i := 1 to 5 do
add(i,s1);
for i := 3 to 8 do
add(i,s2);
intersect(s1,s2,s3);
writeln(toString(s3));
readln;
end.
Obvious mistake:
You are using
print:=print+'x'+',';
when you want
print:=print+x+',';
Mistakes in isMember:
member:=false;
you are not setting isMember, the returned value will be "random". You could remove member altogether and always use `isMember?
if s.setsize=0 then
Should be > 0. But it is not needed

Why does my program not output all my data?

program ZZX1;
{$mode objfpc}{$H+}
uses
crt,
wincrt,
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
type
Masquerader = record
Name, CountyCode: string;
Payment: real;
end;
var
Applicant: array[1..10] of Masquerader;
DemList: array[1..10] of string;
BerList: array[1..10] of string;
EsqList: array[1..10] of string;
x:integer;
Y:integer;
DemCounter:integer;
BerCounter:integer;
EsqCounter:integer;
DemAmount:real;
BerAmount:real;
EsqAmount:real;
procedure LoadData;
begin
clrscr;
X:=0;
DemCounter:=0;
BerCounter:=0;
EsqCounter:=0;
DemAmount:=0;
BerAmount:=0;
EsqAmount:=0;
repeat
X:= x+1;
repeat
write('Enter Your County Code DemM or BerM or EsqM: ');
readln(Applicant[x].CountyCode);
until (Applicant[x].CountyCode= 'DemM') or (Applicant[x].CountyCode= 'BerM') or (Applicant[x].CountyCode= 'EsqM');
If Applicant[x].CountyCode = 'DemM' then
begin
write('Enter Your Name: ');
readln(Applicant[x].Name);
write('Enter Your Total Payment: ');
readln(Applicant[x].Payment);
clrscr;
DemCounter:= DemCounter + 1;
DemAmount:= DemAmount + Applicant[x].Payment;
DemList[DemCounter]:= Applicant[x].Name;
end;
If Applicant[x].CountyCode = 'BerM' then
begin
write('Enter Your Name: ');
readln(Applicant[x].Name);
write('Enter Your Total Payment: ');
readln(Applicant[x].Payment);
clrscr;
BerCounter:= BerCounter + 1;
BerAmount:= BerAmount + Applicant[x].Payment;
BerList[BerCounter]:= Applicant[x].Name;
end;
If Applicant[x].CountyCode = 'EsqM' then
begin
write('Enter Your Name: ');
readln(Applicant[x].Name);
write('Enter Your Total Payment: ');
readln(Applicant[x].Payment);
clrscr;
EsqCounter:= EsqCounter + 1;
EsqAmount:= EsqAmount + Applicant[x].Payment;
EsqList[EsqCounter]:= Applicant[x].Name;
end;
until x=6 ;
end;
Procedure PrintData;
begin
Y:= 0;
for y := 1 to 6 do
begin
writeln('Name: ', Applicant[y].Name);
writeln('CountyCode: ', Applicant[y].CountyCode);
writeln('Payment: ', Applicant[y].Payment:0:2);
writeln;
end;
For Y:= 1 to DemCounter do
begin
writeln(DemList[Y]);
writeln(DemCounter,'',' persons are registered in Demerara');
writeln;
writeln('DemTotal:$ ', DemAmount:0:2);
end;
For Y:= 1 to BerCounter do
begin
writeln(BerList[Y]);
writeln(BerCounter,'',' persons are registered in Berbice');
writeln;
writeln('BerTotal:$ ', BerAmount:0:2);
end;
For Y:= 1 to EsqCounter do
begin
writeln(EsqList[Y]);
writeln(EsqCounter,'',' persons are registered in Essequibo');
writeln;
writeln('EsqTotal:$ ', EsqAmount:0:2);
end;
end;
Procedure quit;
begin
writeln('Press <Enter> To Quit');
readln;
end;
begin
LoadData;
PrintData;
quit;
end.
This program currently collects 6 persons and groups them by their countycode, calculating the total amount of persons and money collected by each county.
When I run the program below my expected output is on the screen for a few seconds then it disappears leaving only a piece of the expected output( The end Part). Please assist.
If there are characters in the keyboard buffer when the program reaches the readln; statement in the procedure quit, readln will read those characters and continue onwards rather than waiting for further input before continuing.
To check this, try adding a character variable as a parameter to readln and write the ASCII value of the character out (or check its value in a debugger) to see if there is anything in that variable after the readln.
(EDIT)
After further thinking, I wonder if the code like:
For Y:= 1 to EsqCounter do
begin
writeln(EsqList[Y]);
writeln(EsqCounter,'',' persons are registered in Essequibo');
writeln;
writeln('EsqTotal:$ ', EsqAmount:0:2);
end;
... should actually read something like:
For Y:= 1 to EsqCounter do
begin
writeln(EsqList[Y]);
end;
writeln(EsqCounter,'',' persons are registered in Essequibo');
writeln;
writeln('EsqTotal:$ ', EsqAmount:0:2);
... because otherwise the same values of EsqCounter and EsqTotal will be output EsqCounter times, which seems unnecessary.

Merge sort in parallel

I have using pascal for my parallel language .(I don't like it , but force.) So the
Merge sort in parallel with fork & join not working, can some one tell me why?
here is my code :
program parrallelmergesort;
architecture shared(100);
const
n=100;(*big array*)
size=10;
var
t,globalCounter:integer;
unsorted:array[1..n] of integer;
procedure CallMerge(var lower,mid,high:integer);
var
i,j,k,count:integer;
S:array[1..n] of integer;
BEGIN
i:=lower;
j:=mid+1;
k:=lower;
count:=high-lower+1;
while (i<=mid) and (j<=high) do
begin
if unsorted[i]<unsorted[j] then
begin
S[k] :=unsorted[i];
i :=i+1;
end
else
begin
S[k] :=unsorted[j];
j :=j+1;
end;
k:=k+1;
end;
if i>mid then
begin
while j<=high do
begin
S[k] :=unsorted[j];
j :=j+1;
k :=k+1;
end;
end
else if j>high then
begin
while i<=mid do
begin
S[k] :=unsorted[i];
i :=i+1;
k :=k+1;
end;
end;
for t:=lower to high do
unsorted[t] :=S[t];
end;
procedure CallMergeSort(bottom,up:integer);
var middle,nextOfMiddle:integer;
begin
if up>bottom then
begin
middle := (up+bottom) div 2;
nextofMiddle :=middle+1;
fork CallMergeSort(bottom,middle);
fork CallMergeSort(nextOfMiddle,up);
join;join;
CallMerge(bottom,middle,up);
end;
end;
begin
unsorted[1] :=4; unsorted[2] :=3; unsorted[3] :=10; unsorted[4] :=5; unsorted[5] :=0;
unsorted[6] :=1; unsorted[7] :=8; unsorted[8] :=6; unsorted[9] :=11; unsorted[10] :=12;
CallMergeSort(1,size);
for globalCounter:=1 to size do
writeln(unsorted[globalCounter]);
readln;
end.
When should I use fork ? before CallMergeSort (Recursive) ?
Last lines is main function in pascal.
don't call fork and join inside the rec function.
Just call them twice from the main.

How does this program to count vowels work?

I want to understand this code, especially PROCEDURE
PROGRAM vowels;
USES crt;
{Program that counts the number of vowels in a sentence}
CONST space=' ';
maxchar=80;
TYPE vowel=(a,e,i,o,u);
VAR buffer:ARRAY[1..maxchar] of char;
vowelcount:ARRAY[vowel] of integer;
PROCEDURE initialize;
VAR ch:vowel;
BEGIN
FOR ch:=a TO u DO
BEGIN
vowelcount[ch]:=0;
END;
END;
PROCEDURE textinput;
VAR index:integer;
BEGIN
writeln('Input a sentence');
FOR index:=1 TO maxchar DO
IF eoln THEN buffer[index]:=space
ELSE read(buffer[index]);
readln;
END;
PROCEDURE analysis;
VAR index:integer;
ch:vowel;
BEGIN
index:=1;
WHILE index<>maxchar+1 DO
BEGIN
IF buffer[index] IN ['a','e','i','o','u'] THEN
BEGIN
CASE buffer[index] OF
'a':ch:=a;
'e':ch:=e;
'i':ch:=i;
'o':ch:=o;
'u':ch:=u;
END;
vowelcount[ch]:=vowelcount[ch]+1;
END;
index:=index+1;
END;
END;
PROCEDURE vowelout;
VAR ch:vowel;
BEGIN
clrscr;
writeln;
writeln(' a e i o u');
FOR ch:=a TO u DO
write(vowelcount[ch]:4);
writeln;
END;
BEGIN
initialize;
textinput;
analysis;
vowelout;
END;
Overall: Okay this code is counting the number of vowels supplied in the input string.
Lets Begin....
TYPE vowel=(a,e,i,o,u); VAR
buffer:ARRAY[1..maxchar] of char;
vowelcount:ARRAY[vowel] of integer;
This code is defining a list of the vowels in english (a,e,i,o,u).
PROCEDURE initialize; VAR ch:vowel;
BEGIN FOR ch:=a TO u DO BEGIN
vowelcount[ch]:=0; END; END;
It then defines a variable to collect the number of each vowel, called vowelcount. That variable is an array, looks sort of like this:
vowelcount[a]=0;
vowelcount[e]=0;
vowelcount[i]=0; #... etc
Then the procedure "Analysis" is defined. This takes the input from the screen (which will be called later on in the program) and steps through each letter in the input.
WHILE index<>maxchar+1 DO BEGIN IF
buffer[index] IN ['a','e','i','o','u']
THEN BEGIN CASE buffer[index] OF
'a':ch:=a; 'e':ch:=e; 'i':ch:=i;
'o':ch:=o; 'u':ch:=u; END;
If any of those letters happens to be in the list of letters than matches a vowel, then it will add one to the number in the vowelcount array above. (vowelcount[ch]:=vowelcount[ch]+1) where ch is the matched letter. As you can see this is only triggered if it is a valid vowel (IF buffer[index] IN ['a','e','i','o','u'] )
Finally. The main code of the program, or what is actually run:
BEGIN clrscr; writeln; writeln(' a e i
o u'); FOR ch:=a TO u DO
write(vowelcount[ch]:4); writeln; END;
BEGIN initialize; textinput; analysis;
vowelout; END.
This basically strings the application together, starting by clearing the screen (in a dos prompt) and then outputting the vowels onto the screen. It then adds some formatting and outputs the current count of vowelcount (as above).
It will then request your input and finally it will output the contents of vowelcount again, which has been updated with the vowelcounts from the input you made.

Resources