Pascal - Greatest Common Divisor - No Output - pascal

Thank you for all help in advance. I have to start programming in Pascal and to e quite honest it's not all that pleasant change from Java and Python. I tried a simple program to return GCD, but console won't even stay open despite the readln at the end.
program App1Learning;
var
a, b : integer;
begin
read(a);
read(b);
while a <> b do
begin
if a < b then b := b - a;
if a > b then a := a - b;
end;
writeln(a);
readln;
end.

Not knowing which Pascal you are using, I tried this in FreePascal 3.0.0 for Windows:
program App1Learning;
var
a, b : integer;
begin
readln(a);
readln(b);
// Or, instead of the two previous lines: readln(a, b);
while a <> b do
begin
if a < b then b := b - a;
if a > b then a := a - b;
end;
writeln(a);
readln;
end.
Read(), while it depends on buffered line input, does not wait for a carriage return, so it will read two numbers but not consume the final carriage return, i.e. this is still in the input buffer. After the program calculates the GCD and displays it, the carriage return that is still in the buffer will be immediately read by the final readln, so the console closes right afterward (readln doesn't have to wait for a carriage return, as it is already — or still — in the buffer).
If you use readln(a); etc. instead, each number will be input on its own line and the function waits for a carriage return and consumes it. This means that the final readln will not find a carriage return in the input buffer, so it will wait until you press Enter.

Related

My program won't print out correct math numbers

I'm coding a little program but it won't print out the right math answer, it just stays at 993.
The Code:
program _Gul_;
uses crt;
var a: integer;
var b: integer;
begin
writeln('1000 - 7?');
a := 1000;
b := a - 7;
while a > 0 do
begin
writeln (a - 7, ' - 7?');
delay(120);
a := a - 7;
writeln (b)
if a = 6 then
break;
end;
writeln('я гуль')
end
I don't quite know why it is not working. I defined "b" and made a command that prints it out and the output is just:
You never update the value in b. In point of fact, b is not necessary to your program at all. Your printing strategy is also more complicated than it needs to be. Print a minus 7, then do the subtraction and print it. This prevents the program telling you the rest of 6 - 7 is 6.
program _Gul_;
uses
crt;
var
a: integer;
begin
a := 1000;
while a > 0 do
begin
writeln (a, ' - 7?');
delay(120);
a := a - 7;
writeln (a);
if a = 6 then
break;
end;
writeln('я гуль')
end.

Rewrite Pascal for do loop using while do loop

Please how do I rewrite the below FOR....DO loop into a WHILE...DO loop in Pascal programming
Below is the following code
Program Matmuli(input,output);
:
:
FOR i:=1 TO m DO
FOR j:=1 TO p DO
BEGIN
C[i,j]:= 0.0;
FOR k:=1 TO n DO
C[i,j]:= C[i,j] + A[i,k] * B[k,j];
END;
The for loop is well defined in terms of a while loop, confer ISO 7185 “Standard Pascal”, quote:
Apart from the restrictions imposed by these requirements, the for-statement
for v := e1 to e2 do body
shall be equivalent to
begin
temp1 := e1;
temp2 := e2;
if temp1 <= temp2 then
begin
v := temp1;
body;
while v <> temp2 do
begin
v := succ(v);
body
end
end
end
[…]
where temp1 and temp2 denote auxiliary variables that the program does not otherwise contain, and that possess the type possessed by the variable v […]
The important thing from this expanded piece of code is, as linuxfan says Reinstate Monica already noted, that in Pascal the limits of a for loop are only evaluated once. Furthermore, the control-variable is only assigned a value if there was indeed at least one iteration.
However, usually it’s sufficient to transform a for loop as Andreas Rejbrand already suggested, although it is technically not the same.

TPascal, Stack Overflow, Recursion

My program should inverse a string (ex. for Hello world returns dlrow olleH) and it works only for strings smaller than 20 characters. For 20 or more i get "Error 202 Stack overflow". Thank you :)
Program Inv;
var S, A: String;
n: integer;
Function I(X: String; z: integer):String;
begin
if z=1 then I:=X[z] else
I:=X[z]+I(X, z-1);
end;
begin
write ('Enter your text: ');
readln (S);
n:=length(S);
A:=I(S, n);
writeln (A);
readln;
end.
Unless you are required to show a recursive solution, you're usually better to sticking with iteration(a). Recursion uses an often-limited resource (the stack) to weave its magic and is often the cause of crashes when you exceed that limit.
Iterative solutions tend to be far less restrictive, such as the code below:
program PaxCode;
Function reverse(inp_str: string) : string;
var out_str : string = '';
var idx : integer = 1;
begin
while (idx <= length(inp_str)) do
begin
out_str := inp_str[idx] + out_str;
idx := idx + 1
end;
reverse := out_str
end;
var test_str: string = 'My hovercraft is full of eels and they will not let me drive it';
begin
writeln(test_str);
writeln(reverse(test_str))
end.
As you can see, the output is correct, and not limited to twenty (or twenty-nine) characters:
My hovercraft is full of eels and they will not let me drive it
ti evird em tel ton lliw yeht dna slee fo lluf si tfarcrevoh yM
(a) The best areas for recursion are those where each level removes a sizable proportion of the solution space. For example, binary searches remove fully 50% of the remaining solution space on every level so you could search through a structure holding four billion entries with just thirty-two levels, since 232 is a touch above 4.2 billion.
Something like reversing a 400-character string will take, ..., let me think, oh yes, 400 levels. That won't necessarily end well :-)

Most repeated character in a row

My task is to show most used letter in a row. For example if you put in aabbbbccbbb most repeated character is B and it is used 4 times. There was a very similar topic about the same task, but i didnt understand the code. Most repeating character in a string
Program Task;
var s:string;
i,k,g,count:integer;
c:char;
begin
Readln(s);
g:=0;
while Length(s) > 0 do
begin
c := s[1];
i:=1;
while i<= Length(s) do
begin
If (c=s[i]) then
delete(s,i,1)
else
Inc(i);
If (c=s[i]) then
Inc(g);
end;
end;
Writeln(g);
Readln;
end.
There are many problems i face. First is i dont know how to show which character is most used and second is i dont know how compare which one of repeating characters is most used.
For example if i write aaaabbbc it will give me answer of 7 because there is 4xa and 3xb.
All the help is most appreciated.
If it's just about english characters, you might just allocate an array to keep a count per character. In that case, the code could look like this.
I wrote this using Delphi. I hope it works as well in your flavour of Pascal.
program Task;
{$APPTYPE CONSOLE} // For Delphi
var
s: string[50];
i: Integer;
Counters: array[Char] of Integer;
Highest: Char;
begin
// Initialize counters.
for i := 0 to 255 do
Counters[Char(i)] := 0;
s := 'aabbbbccbbb';
// Count the characters.
for i := 1 to Length(s) do
Inc(Counters[s[i]]);
// Find out which one is highest.
Highest := #0;
for i := 0 to 255 do
if Counters[Char(i)] > Counters[Highest] then
Highest := Char(i);
// Output that character and its count.
WriteLn('The highest character is ', Highest, ' with ', Counters[Highest], ' occurrences.');
ReadLn;
end.
In less academic setups, using an array like this might not be the most efficient, because it contains a counter for every possible character, including those that don't occur in the string at all. That means, if you want to use this exact code for every possible character in the unicode table, your array would be a couple of megabytes large (still not really a problem on modern computers, but still).
You can improve this code by using a kind of dictionary or list to keep track of the items, so you need only to add those items you find, but if you have to write that yourself, it will make your program quite a bit larger.
EDIT:
As per request in comment: Counting the longest subsequent range of characters:
program Task;
{$APPTYPE CONSOLE} // For Delphi
var
s: String;
i: Integer;
Longest: Integer;
Current: Integer;
LongestChar: Char;
begin
s := 'aabbbbccbbb';
Longest := 0;
Current := 0;
// Count the characters.
for i := 1 to Length(s) do
begin
Inc(Current);
// If it's the last char or the next char is going to be different, restart the counting.
if (i = Length(s)) or (s[i] <> s[i+1]) then
begin
if Current > Longest then
begin
Longest := Current;
LongestChar := s[i];
end;
Current := 0;
end;
end;
// Output that character and its count.
WriteLn('The highest character is ', LongestChar, ' with ', Longest, ' occurrences.');
ReadLn;
end.
Current > Longest makes sure the first longest sequence is returned in case multiple character sequences have the same length. Change to Current >= Longest if you want the last sequence instead.

When the program runs, writes ->->->->. Why does it do that?

Here is the textfile that the program must read, and put every num. in a different variable.
The first num., in this case 3, is the n, and tells the procedure the program how many times to be done. Between the nums., there is a space.
The text file f is like that
3 2
2 1
1 5
4 2
When it runs the code the following thing keeps being writen
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
Why do that happeen?
Can anyone please help me with this program?
The code is the following one.
Program thefinalp;
Uses SysUtils;
Var
f: Text;
m, d: Integer;
n: Char;
c: String[1];
a, e: array of Integer;
LowArr: Integer;
HighArr: Integer;
ArrayLen: Integer;
i: Integer;
begin
Assign(f, 'd:\tempfiles\finalp.txt');
Reset(f);
repeat
Readln(f, n);
Write(n);
until (n = ' ');
Read(f, c);
Write(c);
while not SeekEoln(f) do
begin
read(f, d);
Write(d);
End;
Readln;
Writeln;
StrToIntDef(n, m);
setlength(a, m);
LowArr := Low(a);
HighArr := High(a);
ArrayLen := Length(a);
setlength(e, m);
LowArr := Low(e);
HighArr := High(e);
ArrayLen := Length(e);
for i := LowArr to HighArr do
begin
repeat
Read(f, a[i]);
Write(a[i]);
until (n = ' ');
Read(f, c);
Write(c);
while not SeekEoln(f) do
begin
read(f, e[i]);
Write(e[i]);
End;
Readln;
Writeln;
End;
Readln;
End.
In your first repeat until, you are readlning into a char. The first character will appear in n and the remainder of the characters will be skipped entirely until the newline has been read. AT that point, your file-pointer will be at 2 on the second line of data.
Since your test is for n=' ' then the readln will again be executed, this time delivering 2 into n and pushing the file-pointer to the 1 on the third line.
When eventually end-of-file is reached, a Control-Z character is 'read' from the file. This is the character you are seeing. Since it isn't Space, the loop continues forever.
Change the readln here to a read and one character will be read. (then it works, and you can go on to the next problem...)
Remember, readln reads until it has read a newline. Read reads into the variable - if it's a char, it reads one char. If it's a string, it reads a string - but not the newline.
Program thefinalp;
Uses SysUtils;
Var
f:Text;
m,d:Integer;
n:string;
n2:string;
c:String[1];
a,e:array of integer;//dynamic array//
LowArr:Integer;
HighArr:Integer;
ArrayLen:Integer;
i:Integer;
ch : char;
function readinteger : string;
var
st : string;
begin
st := '';
// read up to first digit
repeat
read(f,ch);
write(ch);
until ch in ['0'..'9'];
//accumulate digits
repeat
st := st + ch;
read(f,ch);
write(ch);
until not (ch in ['0'..'9']);
readinteger := st;
end;
begin
Assign(f,'q21366050.txt');
Reset(f);
// read first integer
n:= readinteger;
// read second integer
n2:= readinteger;
m := StrToInt(n); //puts a string into an integer//
setlength(a,m);
LowArr:=Low(a);
HighArr:=High(a);
ArrayLen:=Length(a);
setlength(e,m);
LowArr:=Low(e);
HighArr:=High(e);
ArrayLen:=Length(e);
for i:= LowArr to HighArr do
begin
// read first integer
n:= readinteger;
// read second integer
n2:= readinteger;
a[i]:=StrToInt(n); //puts a string into an integer//
e[i]:=StrToInt(n2); //puts a string into an integer//
End;
Writeln;
writeln('Results');
for i:= LowArr to HighArr do
writeln(inttostr(i),'=',inttostr(a[i]),',',inttostr(e[i]));
// pause to read results
Readln;
End.
Unfortunately, it's a little difficult to figure out just exactly what you want to do. This routine will read the first line and then put the remaining lines into a[?] and e[?].
Using descriptive variablenames would perform some of the documentation so you can follow what is happening. Since I don't actually know, I'm having to make assumptions and make a few things up to fill in the gaps.
Looking at the main routine, first you assign a filename (I used q21366050.txt for my convenience) and open the file with a reset.
Next job is to read the first number in from the file. Now you have only shown single-digit numbers, but it's easy to set the routine to cope with a sequence.
n:=readinteger;
assigns the result of the function readinteger to the string n
readinteger works this way: first clear the string st which is a "local variable" - only available to this routine. Then keep reading characters into ch until the character read is in the range '0'..'9' - so it skips until it reads a digit. Then it adds the digit read to the string st and continues to read characters and accumulate them until the character found is not a digit. (That character, should we need it, is in ch) We then assign the accumulated string of digits to the resut of the function.
Hence, n will get the first string of digits in the file; the next character has been read,and we know it isn't a digit (otherwise it would have been appended to the string returned).
We then repeat the process with n2. All of the remaining characters before then next digit are skipped, the digit sequence returned and the following character placed in ch
Then we assign the resullt of converting the string n to an integer to m. You haven't described what the other number may be used for, so it's there - but unused.
Set up the two arays, a and e.
Then use the same routine to read the next integer. It doesn't matter that there are CRLF characters - we skip to the next numeric and return it. and repeat that for the second number in the line.
Convert the two numbers and put them into their respective arrays.
Do this m times.
inally, write a new line to the display, then another reporting Results and then repeat m times write a line containing the iteration number i and the values of the two arrays, a and e, all as integers-converted-to-strings and with = and , characters to show that we're not just repeating the dat read from the input.
Finally, wait for an input from the keyboard (since the readln has no explicit filevar) which holds the program open until we can see the results.
Now - nominally, of course, you should also close the file before terminating...

Resources