Find the second highest value - pascal

I've wrote this Code to find out the second highest value in an Array:
var
i,
ZweitMax,
Max : integer;
begin
Max := -maxint;
ZweitMax := -maxint;
for i := 1 to FELDGROESSE do
if inFeld[i] > Max then
begin
ZweitMax := Max;
Max := inFeld[i];
end
else
if inFeld[i] > ZweitMax then
begin
ZweitMax := inFeld[i];
FeldZweitMax := ZweitMax;
end
end;
Where is the Problem in this Code and why it don't print out the right value?
Information: The Code is part of a function FeldZweitMax

There are currently two places where you set ZweitMax but only one of them also affects the return code of the function, FeldZweitMax.
The first part of the if statement can be changed into:
if inFeld[i] > Max then
begin
ZweitMax := Max;
FeldZweitMax := ZweitMax; (* add this line *)
Max := inFeld[i];
end
(* and so on *)
so as to ensure the return value is updated correctly.
Alternatively, you can just set ZweitMax alone in both places and then set the return value at the end:
for i := 1 to FELDGROESSE do
begin
if inFeld[i] > Max then
begin
ZweitMax := Max;
Max := inFeld[i];
end
else
begin
if inFeld[i] > ZweitMax then
begin
ZweitMax := inFeld[i];
end
end
end;
FeldZweitMax := ZweitMax;
I actually prefer the latter since the calculation and return of the value are separate matters.

Related

How can I show the sorting progress step by step on output screen?

I don't know how to make sorting process visible on output.. (like you can see the step by step of each sorting phase on output).
Below is example of a similar program.
And here's my current progress:
program insertsort;
const
max = 100;
type
arr = array [1..max] of integer;
var
data : arr;
n, i, j : integer;
procedure InsertionSort(size : integer);
var
i, j, index : integer;
begin
for i := 2 to size do
begin
index := data[i];
j := i;
while ((j > 1) and (data[j-1] < index)) do
begin
data[j] := data[j-1];
j := j - 1;
end;
data[j] := index;
end;
end;
begin
write('Input Data : ');
readln(n);
for i := 1 to n do
begin
write ('Data-',i,' = '); readln(data[i]);
end;
writeln;
write ('Unsorted : ');
for i := 1 to n do
write(data[i],' ');
InsertionSort(max);
writeln;
writeln;
writeln;
write('Sorted : ');
for i := 1 to n do
write(data[i],' ');
readln;
end.

What is that the Error of Illegal assignment and how to correct it?

procedure tri_selection(t: tab; n: Integer);
var
i, j, min, aux: Integer;
begin
for i := 1 to n - 1 do
begin
min := i;
for j := i + 1 to n do
if t[j] < t[min] then
j := min;
if min <> i then
begin
aux := t[i];
t[i] := t[min];
t[min] := aux;
end;
end;
end;
That's supposed to be a correct and well-known code to arrange integers from inferior to superior but compiler still insists saying "illegal assignment to for loop 'j' variable".
What's the problem?
The problem is here:
for j := i + 1 to n do
if t[j] < t[min] then
j := min; // <-- Not allowed to assign to FOR loop variable j
You are not allowed to assign to the for loop variable.
Perhaps you meant to write
for j := i + 1 to n do
if t[j] < t[min] then
min := j;
you forgot var before t in the header of the procedure

Program behaving differently in FPC and ObjFPC

Following is a program in lazarus to perform RC4 encryption and decryption when given a string. When the compiler directive {$mode fpc} is used and the string 123 is entered it crashes with External: SIGSEGV. However there is no crash when inputting the same string in {$mode objfpc}. Another inconsistency is that in {$mode objfpc} the program raises the exception External: SIGSEGV again with the input of hellow.
//{$mode fpc}
{$mode objfpc}
program project1;
uses
sysutils, strutils;
type
myArray = array[0..255] of integer;
dynamicArray = array of integer;
dynamicArrayString = array of string;
const
key = 'qwertyui';
var
plaintext : string;
function KSA(const key: string): myArray;
var
i, j, key_length, temp: integer;
S : myArray;
begin
key_length := length(key);
j := 0;
for i := Low(S) to High(S) do
S[i] := i;
for i := Low(S) to High(S) do
begin
j := ((j + S[i] + ord(key[i mod key_length + 1])) mod 256);
temp := S[i];
S[i] := S[j];
S[j] := temp;
end;
KSA := S;
end;
function PRGA(S : myArray; n : integer) : dynamicArray;
var
i, j, K, temp, sizeOfArray : integer;
key : dynamicArray;
begin
i := 0;
j := 0;
K := 0;
temp := 0;
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
while n > 0 do
begin
n := n - 1;
i := (i + 1) mod 256;
j := (j + S[i]) mod 256;
temp := S[i];
S[i] := S[j];
S[j] := temp;
K := S[(S[i] + S[j]) mod 256];
key[i-1] := K;
end;
PRGA := key;
end;
procedure getPlaintext;
begin
readln(plaintext);
end;
function encrypt : string;
var
sizeOfArray, i : integer;
cipherString : string;
cipher, keystream: dynamicArray;
S : myArray;
begin
S := KSA(key);
keystream := PRGA(S, length(plaintext));
sizeOfArray := 0;
for i := 0 to (length(plaintext) - 1) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(cipher, sizeOfArray);
cipher[i] := (keystream[i]) xor (ord(plaintext[i + 1]));
end;
cipherString := '';
for i := 0 to High(cipher) do
cipherString := cipherString + IntToHex(cipher[I], 2);
encrypt := cipherString;
end;
function stringToHex(cipherString : string) : dynamicArrayString;
var
sizeOfArray, i: integer;
DecryptArrayString : dynamicArrayString;
begin
sizeOfArray := 0;
i := 0;
// Turn the string into an array of hex
while length(cipherString) > 0 do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(DecryptArrayString, sizeOfArray);
DecryptArrayString[i] := cipherString[1] + cipherString[2];
i := i + 1;
cipherString := rightstr(cipherString, length(cipherString) - 2);
end;
stringToHex := DecryptArrayString;
end;
function hexToDecimal(DecryptArrayString : dynamicArrayString) : dynamicArray;
var
sizeOfDecryptArrayInt, i : integer;
DecryptArrayInt : dynamicArray;
begin
sizeOfDecryptArrayInt := 0;
// Hex to decimal
for i := 0 to high(DecryptArrayString) do
begin
sizeOfDecryptArrayInt := sizeOfDecryptArrayInt + 1;
SetLength(DecryptArrayInt, sizeOfDecryptArrayInt);
DecryptArrayInt[i] := Hex2Dec(DecryptArrayString[i]);
end;
hexToDecimal := DecryptArrayInt;
end;
function decrypt(DecryptArrayInt : dynamicArray) : string;
var
DecryptedString : string;
S : myArray;
keystream, Decrypted : dynamicArray;
sizeOfArray, i : integer;
begin
sizeOfArray := 0;
for i := 0 to high(DecryptArrayInt) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(Decrypted, sizeOfArray);
S := KSA(key);
keystream := PRGA(S, length(plaintext));
Decrypted[i] := (keystream[i] xor DecryptArrayInt[i]);
end;
decryptedString := '';
// Turn array to string
for i := 0 to high(Decrypted) do
decryptedString := decryptedString + chr(Decrypted[i]);
decrypt := decryptedString;
end;
procedure encryptDecrypt;
var
cipherString, DecryptedString : string;
DecryptArrayString : dynamicArrayString;
DecryptArrayInt : dynamicArray;
begin
cipherString := encrypt;
writeln(cipherString);
DecryptArrayString := stringToHex(cipherString);
DecryptArrayInt := hexToDecimal(DecryptArrayString);
DecryptedString := decrypt(DecryptArrayInt);
writeln(DecryptedString);
end;
begin
getPlaintext;
encryptDecrypt;
readln;
end.
I've not been able to find the many specific cases that makes the program crash apart from a string of any three characters will always crash in {$mode fpc} but not in {$mode objfpc}
You should debug (and watch) your code so any error can be traced more easily. Use the FP IDE, it helps a lot.
Meanwhile, watch this line:
keystream := PRGA(S, length(plaintext));
And inside the PRGA function watch these lines:
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
What's wrong here? Well, suppose "plaintext" has only 1 character. So, "Length(plaintext)"=1, right? In PRGA you do "sizeOfArray:= n-1;", so sizeOfArray = 0. When you do SetLength, "Key" will be NIL because you're indicating a zero indexes length. Later, on loop, you have:
key[i-1] := K;
the program will fail because you are accessing at index 0 and the Key variable is NIL.
Careful: On "SetLength(key, sizeOfArray);" valid indexes for key are in range [0..sizeOfArray-1], but sizeOfArray must be at least 1 to be valid (sizeOfArray >= 1).
So, you should check your PRGA function. It's up to you to find the definitive solution. Don't give up. Good luck!

GET_TIME in Oracle

I have a code that is supposed to give me the compilation time for the procedure, but it only gets me 0 secs! Is the calculation wrong? Is there any other way?
create or replace PROCEDURE proc_time AS
v NUMBER := 1;
x NUMBER := 0;
counter number := 0;
summ NUMBER;
ex_start NUMBER;
ex_end NUMBER;
ex_time NUMBER;
BEGIN
ex_start := dbms_utility.get_time;
while counter <= 19
loop
counter := counter + 1;
summ := x+v;
x := v;
V := summ;
dbms_output.put_line('Fibonacci nr'||counter||': '||summ);
END loop;
ex_end := DBMS_UTILITY.GET_TIME;
ex_time := (ex_end-ex_start)/100;
DBMS_OUTPUT.PUT_LINE( 'Exekveringstid: ' || ex_time || ' sekunder.' );
END;
/
As explained in the above answer by Lalit. Your snippet runs too fast
to calculate the time difference. Try to increase the while loop with
some greater number and here you go !!!
CREATE OR REPLACE PROCEDURE proc_time
AS
v NUMBER := 1;
x NUMBER := 0;
counter NUMBER := 0;
summ NUMBER;
ex_start NUMBER;
ex_end NUMBER;
ex_time NUMBER;
BEGIN
ex_start := dbms_utility.get_time;
dbms_output.put_line('start time ==>'||NVL(ex_start,0));
WHILE counter <= 190000
LOOP
counter := counter + 1;
summ := x +v;
x := v;
V := summ;
-- dbms_output.put_line('Fibonacci nr'||counter||': '||summ);
END LOOP;
ex_end := DBMS_UTILITY.GET_TIME;
dbms_output.put_line('End time ==>'||ex_end);
ex_time := (ex_end-ex_start);
DBMS_OUTPUT.PUT_LINE( 'Exekveringstid: ' || ex_time || ' sekunder.' );
END;
set serveroutput on;
exec proc_time;
-------------------------------OUTPUT----------------------------------------
start time ==>1761607275
End time ==>1761607281
Exekveringstid: 6 sekunder.
As an alternative use the TIMESTAMP data type, this supports up to nanoseconds (provided your server supports it as well)
DECLARE
ex_start TIMESTAMP(9);
Duration INTERVAL DAY TO SECOND;
v NUMBER := 1;
x NUMBER := 0;
counter NUMBER := 0;
summ NUMBER;
BEGIN
ex_start := LOCALTIMESTAMP;
WHILE counter <= 10000 LOOP
counter := counter + 1;
summ := x +v;
x := v;
V := summ;
END LOOP;
Duration := LOCALTIMESTAMP - ex_start;
DBMS_OUTPUT.PUT_LINE ( EXTRACT(SECOND FROM Duration) /1000||' msec.');
END;
Perhaps, it is executing too quickly. You can try to increase the number of loops instead of 19 to something larger.
Also, it would give you the execution time, not the compilation time. The procedure is already compiled and stored in database. The time in the output is at run time, i.e. when you execute the procedure.
For example,
SQL> CREATE OR REPLACE PROCEDURE test_time
2 AS
3 l_start NUMBER;
4 l_loops NUMBER := 10000000;
5 l_number NUMBER := 0;
6 BEGIN
7 l_start := DBMS_UTILITY.get_time;
8 FOR i IN 1 .. l_loops
9 LOOP
10 l_number := l_number + i;
11 END LOOP;
12 DBMS_OUTPUT.put_line('time taken: ' || (DBMS_UTILITY.get_time - l_start) || ' hsecs');
13 END test_time;
14 /
Procedure created.
SQL> set serveroutput on
SQL> BEGIN
2 test_time;
3 END;
4 /
time taken: 101 hsecs
PL/SQL procedure successfully completed.
SQL>

How to write numbers separated with commas in a loop on one line?

I am making a program of prime number in FreePascal.
How to output number divides with I1,I2 separated with commas instead of 2 lines?
var
P:Integer;
I:Integer;
J:Integer;
A:Integer;
begin
writeln('Prime number program');
writeln;
writeln('Insert number');
readln(P);
for I:=2 to P-1 do
begin
J:=P Mod I;
if (J=0) then
begin
writeln(P,' divides with ',I);
a:=a+1
end;
end;
if a=0 then
begin
writeln(P,' is prime number')
end;
end.
I know it's not a good way to teach you something, but here it is:
program Project1;
uses
SysUtils;
var
S: string;
I: Integer;
Count: Integer;
Input: Integer;
begin
Writeln('Prime number program');
Writeln;
Writeln('Insert a number:');
Readln(Input);
for I := 2 to Input-1 do
begin
if (Input mod I = 0) then
begin
Count := Count + 1;
if (S <> '') then
S := S + ', ';
S := S + IntToStr(I);
end;
end;
if (Count = 0) then
Writeln(Input, ' is a prime number.')
else
Writeln(Input, ' is not a prime number. It divides with ', S, '.');
Readln;
end.
prime := true;
for i := 2 to p - 1 do
if(p mod i = 0) then prime := false;
if prime then writeln("prime");
all program:
program Prime;
var
prime: boolean;
I, P: Integer;
begin
Writeln('Prime number program');
Writeln;
Writeln('Insert a number:');
Readln(P);
prime := true;
for i := 2 to p - 1 do
if(p mod i = 0) then prime := false;
if prime then writeln("prime");
else writeln("not prime");
Readln;
end.
No need to check all numbers below N, odd numbers below sqrt(N) are enough.
program PrimeTest;
var N, I, Divisor: LongInt;
Prime: Boolean;
begin
writeln('Prime number program');
writeln;
write('Insert number: ');
readln(N);
Divisor := 1;
Prime := True;
if N < 5 then
begin
Prime := (N = 2) or (N = 3);
if N = 4 then Divisor := 2;
end else if Odd(N) then
begin
I := 3;
while I*I <= N do
begin
if N mod I = 0 then
begin
Prime := False;
Divisor := I;
break;
end;
I := I + 2;
end;
end else begin
Prime := False;
Divisor := 2;
end;
if Prime then writeln(N, ' is a prime number')
else writeln(N, ' is divisible by ', Divisor);
end.
Of course, if you want to find all prime factors, or all divisors (not the same thing), you will need something a bit more complcated, but it's still better to do as few divisions as possible.
Here is a solution giving the whole prime factorization.
program PrimeTest;
var N, I, J, Index, M: LongInt;
Factor, Power: array[1 .. 32] of LongInt;
begin
writeln('Prime number program');
writeln;
write('Insert number: ');
readln(N);
M := N;
Index := 0;
if N mod 2 = 0 then
begin
J := 0;
while N mod 2 = 0 do
begin
Inc(J);
N := N div 2;
end;
Inc(Index);
Factor[Index] := 2;
Power[Index] := J;
end;
I := 3;
while I*I <= N do
begin
if N mod I = 0 then
begin
J := 0;
while N mod I = 0 do
begin
Inc(J);
N := N div I;
end;
Inc(Index);
Factor[Index] := I;
Power[Index] := J;
end;
I := I + 2;
end;
if (N > 1) or (Index = 0) then
begin
Inc(Index);
Factor[Index] := N;
Power[Index] := 1;
end;
if M = 1 then writeln('1 is not prime')
else if (Index > 1) or ((Index > 0) and (Power[1] > 1)) then
begin
if Power[1] = 1 then write(M, ' = ', Factor[1])
else write(M, ' = ', Factor[1], '^', Power[1]);
for I := 2 to Index do
begin
if Power[I] = 1 then write(' * ', Factor[I])
else write(' * ', Factor[I], '^', Power[I]);
end;
writeln;
end else writeln(M, ' is prime');
end.

Resources