Reverse the given number program in PL/SQL - oracle

I was trying to execute this program but it only outputs the ~ symbol.
This is the code:
DECLARE
N_NUM NUMBER := 234;
N_REM NUMBER;
N_REV NUMBER := 0;
BEGIN
WHILE N_NUM != 0
LOOP
N_REM := MOD (N_NUM, 10);
N_NUM := (N_NUM / 10);
N_REV := N_REV * 10 + N_REM;
END LOOP;
DBMS_OUTPUT.PUT_LINE (N_REV);
END;

Before dividing by 10 you have to subtract the remainder. The following code will work.
DECLARE
N_NUM NUMBER := 234;
N_REM NUMBER;
N_REV NUMBER := 0;
BEGIN
WHILE N_NUM <> 0
LOOP
N_REM := MOD (N_NUM, 10);
N_NUM := ( (N_NUM - N_REM) / 10);
N_REV := N_REV * 10 + N_REM;
END LOOP;
DBMS_OUTPUT.PUT_LINE (N_REV);
END;

Use Floor function as shown below:
N_NUM := FLOOR(N_NUM/10)
As this floor function returns only 23 instead of 23.4

A second option is using the REVERSE() function.
However, that function would like to input a CHAR, not a NUMBER.
So you will have to convert that first.
For example:
DECLARE
N_Num NUMBER := 234;
N_Rev NUMBER := 0;
BEGIN
SELECT REVERSE(TO_CHAR(N_Num)) INTO N_Rev FROM Dual;
DBMS_OUTPUT.PUT_LINE (N_Rev);
END;
/

create or replace function ReverseNo(no1 in number)
return number
Is
n number:=no1;
p number;
c number:=0;
begin
while ( n>0)
LOOP
p:=mod(n,10);
c:=c*10+p;
n:=(n-p)/10;
END LOOP;
DBMS_OUTPUT.PUT_LINE('NO IS ' || c);
return c;
end;

Related

Error: BREAK not allowed in for looping pascal

I try to create a for looping for my Bubble Sort Algorithm and use break as a condition if there is no more number to be sorted anymore. But then the compiler said that BREAK not allowed. Here is my code
Procedure Sort(var data : arr; j : integer);
var
temp: integer;
begin
temp := data[j];
data[j] := data[j + 1];
data[j + 1] := temp;
end;
Procedure sortDescending(var data : arr; n : integer);
var
i, j : integer;
marker : boolean;
begin
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
end;
Here's your code.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
Let's add some whitespace after loops and indentation to make the issue clearer.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;
Which is equivalent to:
for i := 1 to n do
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
The break is not within a loop.
You likely meant to put begin before marker := false;.
for i := 1 to n do
begin
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;

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 can I print an associative array as a matrix

I'm creating 2 associative arrays in which I put random values from 0 to 30, and after that I want to print then as a matrix. Is there a way I can do that?
Here is my code:
set serveroutput on
DECLARE
TYPE MyTab IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
mat1 MyTab;
mat2 MyTab;
v_n NUMBER(2);
v_m NUMBER(2);
v_nr NUMBER(3);
v_dim NUMBER(3);
BEGIN
v_n := round(dbms_random.value(2,5));
v_m := round(dbms_random.value(2,5));
v_nr := 1;
v_dim := v_n*v_m;
DBMS_OUTPUT.PUT_LINE(v_n||' '||v_m);
FOR i in 1 ..v_dim LOOP
mat1(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
v_nr := 1;
FOR i in 1 ..v_dim LOOP
mat2(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
FOR i in 1 ..v_dim LOOP
DBMS_OUTPUT.PUT_LINE(mat1(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE(chr(10));
FOR i in 1 ..v_dim LOOP
DBMS_OUTPUT.PUT_LINE(mat2(i));
END LOOP;
END;
/
I just understood there are 2 matrixes, mat1 and mat2, which have various size (but both have same dimensions).
Here is how to display them:
set serveroutput on
DECLARE
TYPE MyTab IS TABLE OF NUMBER INDEX BY pls_integer;
mat1 MyTab;
mat2 MyTab;
v_n pls_integer;
v_m pls_integer;
v_nr pls_integer;
v_dim pls_integer;
BEGIN
v_n := round(dbms_random.value(2,5));
v_m := round(dbms_random.value(2,5));
if (v_n > v_m) then
-- switch values for V_m to be the biggest dim
v_nr:=v_n;
v_n:=v_m;
v_m:=v_nr;
end if;
v_nr := 1;
v_dim := v_n*v_m;
DBMS_OUTPUT.PUT_LINE(v_n||' '||v_m);
FOR i in 1 ..v_dim LOOP
mat1(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
v_nr := 1;
FOR i in 1 ..v_dim LOOP
mat2(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('MATRIX1');
FOR i in 1 ..v_n LOOP
FOR j in 1 ..v_m LOOP
DBMS_OUTPUT.PUT(' - '|| rpad(mat1((j-1)*v_n + i), 4));
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
DBMS_OUTPUT.PUT_LINE('MATRIX2');
FOR i in 1 ..v_n LOOP
FOR j in 1 ..v_m LOOP
DBMS_OUTPUT.PUT(' - '|| rpad(mat2((j-1)*v_n + i), 4));
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
END;
/
I changed the types to pls_integer which looks more simple. Then keep in mind that I put the matrices in the good form where they can be multiplied (swith v_nand v_m in the loops, and added formatting to understand what happens.
DECLARE
TYPE MyTab IS TABLE OF NUMBER INDEX BY pls_integer;
mat1 MyTab;
mat2 MyTab;
v_n pls_integer;
v_m pls_integer;
v_nr pls_integer;
v_dim pls_integer;
idx pls_integer;
idx1 pls_integer;
idx2 pls_integer;
v_p number;
BEGIN
v_n := round(dbms_random.value(2,5));
v_m := round(dbms_random.value(2,5));
-- v_n := 2; -- formating works better with 2 and 3
-- v_m := 3;
v_nr := 1;
v_dim := v_n*v_m;
DBMS_OUTPUT.PUT_LINE(v_n||' '||v_m);
FOR i in 1 ..v_dim LOOP
mat1(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
v_nr := 1;
FOR i in 1 ..v_dim LOOP
mat2(v_nr) := round(dbms_random.value(0,30));
v_nr := v_nr+1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('MATRIX1:a');
FOR i in 1 ..v_n LOOP
DBMS_OUTPUT.PUT(' .................. ');
FOR j in 1 ..v_m LOOP
idx:=(j-1)*v_n + i;
DBMS_OUTPUT.PUT(' |'||j||','||i||'a['||idx||']'|| rpad(mat1(idx), 4));
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
DBMS_OUTPUT.PUT_LINE('MATRIX2:b');
FOR i in 1 ..v_m LOOP
FOR j in 1 ..v_n LOOP
idx:=(j-1)*v_m + i;
DBMS_OUTPUT.PUT(' |'||j||','||i||'b['||idx||']'|| rpad(mat2(idx), 4));
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
DBMS_OUTPUT.PUT_LINE('product: a x b');
FOR L in 1 ..v_m LOOP
DBMS_OUTPUT.PUT(' ---------------------------');
FOR K in 1 ..v_m LOOP
v_p:=0;
DBMS_OUTPUT.PUT(' | ');
FOR j in 1 ..v_n LOOP
idx1 := j + (K-1)*v_n;
idx2 := (j-1)*v_m + L;
v_p := v_p + mat1(idx1) * mat2(idx2) ;
DBMS_OUTPUT.PUT('a['||idx1||']b['||idx2||']+');
END LOOP;
DBMS_OUTPUT.PUT('->'|| rpad(v_p, 4));
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
END;
/
Do you want to use Matrix for calculation or logging?
It is quite difficult to logging with Matrix. I don't think it is a good way. If you insist, here's the code.
FOR i in 1 ..v_n LOOP
FOR j in 1 ..v_m LOOP
DBMS_OUTPUT.PUT( mat.at<double>(i,j));

Permutation of numbers - all possible combinations [duplicate]

this is my simple code to generate
all possible combinations of a set for
example
1,2,3:
Display:
123
132
213
231
312
321
i want to create variable number of for loops to let the user determine the length of given string...
does anyone have an idea...
thank's in advance.
type
TNumber = '0'..'9';
procedure TForm1.Button1Click(Sender: TObject);
var
Numbers: array[0..3] of TNumber;
a, b, c, d: Integer;
s: string;
begin
Numbers[0] := '1';
Numbers[1] := '8';
Numbers[2] := '7';
Numbers[3] := '2';
for a := low(Numbers) to High(Numbers) do
for b := low(Numbers) to High(Numbers) do
for c := low(Numbers) to High(Numbers) do
for d := low(Numbers) to High(Numbers) do
begin
s := Numbers[a] + Numbers[b] + Numbers[c] + Numbers[d];
if
(Occurrences('1', s) > 1 ) or
(Occurrences('8', s) > 1 ) or
(Occurrences('7', s) > 1 ) or
(Occurrences('2', s) > 1 )
then
Continue
else
Memo1.Lines.Add(s);
end;
end;
function TForm1.Occurrences(const Substring, Text: string): Integer;
var
Offset: Integer;
begin
Result := 0;
Offset := PosEx(Substring, Text, 1);
while Offset <> 0 do
begin
Inc(Result);
Offset := PosEx(Substring, Text, offset + length(Substring));
end;
end;
end.
Here is some code that produces the output you desire. You'd need to work it around a bit for your needs, but the concept expressed in this recursive solution is the important thing:
program Permuatations;
{$APPTYPE CONSOLE}
type
TElements = '1'..'3';
procedure EnumerateCombinations(const Stem: string; Len: Integer);
var
i: Integer;
el: TElements;
Used: set of TElements;
begin
if Len=0 then
exit;
Used := [];
for i := 1 to Length(Stem) do
Include(Used, Stem[i]);
for el := low(el) to high(el) do
begin
if el in Used then
continue;
if Len=1 then
Writeln(Stem+el)
else
EnumerateCombinations(Stem+el, Len-1)
end;
end;
procedure Main;
begin
EnumerateCombinations('', 1+ord(high(TElements))-ord(low(TElements)));
end;
begin
Main;
Readln;
end.
Output:
123
132
213
231
312
321
If you change the definition of TElements, for example to '1'..'4' then you will see the 24 possible permutations.

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