Rewrite Pascal for do loop using while do loop - pascal

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.

Related

Pascal - Incompatible type: Got "Array Of Extended", expected "QWord" / error

I am trying to sort an array of 100000 extended numbers using a quicksort algorithm, but I keep getting the following errors when calling the procedure:
source.pas(69,26) Error: Incompatible type for arg no. 1: Got "Array[1..100000] Of Extended", expected "QWord"
source.pas(69,36) Error: Incompatible type for arg no. 1: Got "Array[1..100000] Of Extended", expected "QWord"
program test;
type
TVector = array of double;
var
N,M,i,x:longint;
a,b,c,apod,af: Array[1..100000] of extended;
procedure QuickSort(var apod: TVector; iLo, iHi: Integer) ;
var Lo, Hi: Integer;
pivot,t: double;
begin
if (iHi-iLo) <= 0 then exit;
Lo := iLo;
Hi := iHi;
Pivot := apod[(Lo + Hi) div 2];
repeat
while A[Lo] < Pivot do Inc(Lo);
while A[Hi] > Pivot do Dec(Hi);
if Lo <= Hi then
begin
T := apod[Lo];
apod[Lo] := apod[Hi];
apod[Hi] := T;
Inc(Lo) ;
Dec(Hi) ;
end;
until Lo > Hi;
if Hi > iLo then QuickSort(apod, iLo, Hi) ;
if Lo < iHi then QuickSort(apod, Lo, iHi) ;
end;
begin
{a[i],b[i],c[i],af[i],N,M are initialiazed here}
apod[i]:=(a[i]-((a[i]*b[i])/3000)-((c[i]*a[i])/40));
end;
begin
QuickSort(apod, Lo(apod), Hi(apod)) ;
end;
end.
How can I fix this?
You have several syntactical errors in your code. I did not check if your quicksort is actually correct. You can debug that.
Array types
You are confusing several different things:
dynamic arrays (e.g. type array of double),
static arrays (e.g. type array[a..b] of double) and probably
open array parameters (parameter array of double).
Your parameter is a dynamic array type (TVector), but you pass a static array. These are not compatible.
To be able to pass a dynamic as well as a static array, you can use the mentioned open array parameters (note that they look like, but are not the same as dynamic arrays).
procedure QuickSort(var apod: array of Double; iLo, iHi: Integer);
More about open array parameters in an article of mine: Open array parameters and array of const.
Var (reference) parameters
But there is another problem: var parameters must have the exact type (or base type). No conversion will take place. So your a, b, c, apod and af parameters must contain Doubles too:
var
a, b, c, apod, af: array[1..100000] of Double;
Unbound blocks
Then the loose begin endblocks after the QuickSort function don't make sense. That is not Pascal. Rather do something like this in the main block (the last begin ... end. — note the final .):
begin
for i := Low(apod) to High(apod) do
apod[i] := (a[i] - ((a[i] * b[i]) / 3000) - ((c[i] * a[i]) / 40));
QuickSort(apod, Low(apod), High(apod));
end.
But note that the code above doesn't make a lot of sense. Probably all values in apod will be 0, since a, b, c, etc. are not initialized yet (so a[i] etc. are probably all 0).
I have no idea where you got that code, but you may want to try to understand it, before you start translating it to Pascal.
Lo and Hi
Note that you should use Low and High. Lo and Hi are something totally different: they get the low and high byte of a 16 bit word, respectively. Low and High get the bounds of arrays, sets and types.

Algorithm name for all 2-uplets of a set

I'm looking for the name (and for the code : in PL/SQL or PG/SQL) of the algorithm which is finding all couple (2-uplets) of a set.
Example :
A - B - C
Result :
1 : A - B
2 : A - C
3 : B - C
I know that the powerset algorithm do this part of the job, but I'm looking for an optimised couple finder algorithm.
Link for the powerset pg/sql algorithm : https://www.postgresql.org/message-id/20060924054759.GA71934%40winnie.fuhr.org
Have you considered something like
Select A.x, B.x
From YourTable as A, YourTable as B
Where A.key <> B.key
You mention SQL so this might be preferable. Note that the number of rows in the cross product is about the same as the number of pairs, so it isn't terribly inefficient.
I've build the solution :
CREATE OR REPLACE FUNCTION twouplets(a anyarray)
RETURNS SETOF anyarray AS
$BODY$
DECLARE
retval a%TYPE;
size integer := array_upper(a, 1);
i integer;
j integer;
BEGIN
i := 0;
j := 1;
FOR i IN 1 .. size LOOP
FOR j IN 1 .. size-i LOOP
retval := '{}';
retval := array_append(retval, a[i]);
retval := array_append(retval, a[i+j]);
RETURN NEXT retval;
END LOOP;
END LOOP;
RETURN;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE STRICT
COST 100
ROWS 1000;
ALTER FUNCTION twouplets(anyarray)
OWNER TO postgres;

maximum value of for loop in PL/SQL

I'd like to know, what is the maximum value in a for loop statement?
Is the datatype NUMBER?
BEGIN
-- Bounds are numeric literals:
FOR j IN 1..5000 LOOP
NULL;
END LOOP;
END;
I will need up to 3x10^14
As noted in the documentation, the lower and upper bounds of a for expression are stored in a temporary pls_integer variable. According to pls_integer's documentation, it can hold values from -2147483648 to 2147483647, represented in 32 bits.
You can give yourself some more room with regards to the upper bound on the loop iterator. For example if you have a loop like this:
declare
lower_bound number := 2147483640;
upper_bound number := 2147483650; -- <==Exceeds PLS_INTEGER max value
begin
for i in lower_bound..upper_bound
loop
... do something with i ...
end loop;
end;
that encounters an ORA-01426: numeric overflow error you can rewrite your loop like this:
declare
lower_bound number := 2147483640;
upper_bound number := 2147483650;
i number;
begin
for j in 0 .. upper_bound-lower_bound
loop
i := j + lower_bound;
... do something with i ...
end loop;
end;
In the above code, I've changed the loop iterator from i to j, changed the loop bounds to always iterate from zero to the number of iterations required, and added a new local variable i to be used by your original code. Finally adding i := j + lower_bound; as the first statement inside the loop ensures that your code sees i the way it expects.
Now as long as you aren't iterating 2,147,483,647 times you should be good.
I am not sure, why you may needed this much bigger loop.
may be you can try this
Thanks,
Thangamani Eraniyan
BEGIN
FOR j IN 3 LOOP
begin
FOR K IN 10 LOOP
begin
for L in 14 loop
Null /* you can try your code here */
End Loop;
End Loop;
END LOOP;
END;

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 :-)

small problem In Pascal , Could you please help?

I write this program with pascal
which ask the user to enter two arrays and constant value which is K
the program muli the K with arrays .
and then save the answer in new array
and do some operation in new array
addition << work well
Subtraction << also work
BUT the problem in Multi << I am trying to ask the user to enter a new array and do Muti but still there is a problem.
ALSO
I want these operation repeated until the user press exit <<< I could not do this options because i am not perfect with pascal .
I would be grateful if you could help me
This is My Code
program BST6;
const maxN=100;maxM=100;
type mat=array[1..maxN,1..maxM]of integer;
var A,B,c:mat;
n,m,l,s,i,j,k:integer;
ch : char;
procedure readMat(var A:mat;var m,n:integer);
begin
for i:=1 to m do
for j:=1 to n do
begin
write('mat[',i,',',j,']=');
readln(A[i,j]);
end;
end;
procedure writeMat(A:mat;m,n:integer);
begin
for i:=1 to m do
begin
for j:=1 to n do
write(a[i,j]:4);
writeln;
end;
end;
function multK(A:mat;k:integer):mat;
begin
for i:=1 to n do
for j:=1 to m do
begin
B[i,j]:= K*A[i,j];
end;
multK:=B;
end;
function minus(A,B:mat):mat;
begin
for i:=1 to m do
for j:=1 to n do
C[i,j]:=A[i,j]-B[i,j];
minus:=C;
end;
function plus(A,B:mat):mat;
begin
for i:=1 to m do
for j:=1 to n do
C[i,j]:=A[i,j]+B[i,j];
plus:=C;
end;
function mult(A,B:mat;m,l,n:integer):mat;
begin
for i:=1 to m do
for j:=1 to n do
for k:=1 to l do
c[i,j]:=c[i,j]+A[i,k]*B[k,j];
mult:=C;
end;
begin
write('input m<=',maxM,'.. m=' );readln(m);
write('input n<=',maxN,'.. n=');readln(n);
readMat(A,m,n);
writeln('input the const K');readln(k);
B:=multK(A,K);
writeln('The matrix A : ');
writeMat(A,m,n);
writeln('The matrix B=K*A : ');
writeMat(B,m,n);
writeln('choose the operation + , - or * ');
readln(ch);
case ch of
'+' : c:=plus(A,B);
'-' : c:=minus(A,B);
'*' : begin
writeln('input m<=',maxM,'input l<=',maxN);readln(m,l);readMat(A,m,l);
writeln('input l<=',maxN);readln(n);readMat(B,l,n);
c:=mult(A,B,m,l,n);
end;
end;
writeMat(c,m,n);
readln;
end.
First of all having global one letter variables which collide with function parameters with the same name is insane.
Why does multK modify the global variable B as a sideeffect?
Why does minus modify the global variable C as a sideeffect?
Why global integers as for index variables?
And mult is even worse: It doesn't only modify C as a sideeffect, but it assumes C contains meaningful values beforehand. I think it needs to initialize C to all zeros beforehand.
My guess is some of your side effects interfere in strange ways. But I don't want to think it through. Refactor your code first. In particular learn how and when to use local variables.

Resources