PLSQL (finding range of prime number to 1000 ) - oracle

DECLARE
n NUMBER;<br>i NUMBER;
pr NUMBER;
BEGIN
FOR n IN 2 .. 1000 LOOP
pr := 1;
FOR i IN 2 .. n / 2 LOOP
IF MOD(n, i) = 0 THEN
pr := 0;
END IF;
END LOOP;
IF (N = 997) THEN
DBMS_OUTPUT.PUT(n);
pr:=2;
ELSE
IF pr = 1 THEN
DBMS_OUTPUT.PUT(n||'&');
END IF;
END if;
END LOOP;
dbms_output.new_line;
END;
output should be as in one line----> 2&3&5&7&11&13&17&19&23&29&31&37&41&43&47&53&59&61&67&71&73&79&83&89&97&101&103&107&109&113&127&131&137&139&149&151&157&163&167&173&179&181&191&193&197&199&211&223&227&229&233&239&241&251&257&263&269&271&277&281&283&293&307&311&313&317&331&337&347&349&353&359&367&373&379&383&389&397&401&409&419&421&431&433&439&443&449&457&461&463&467&479&487&491&499&503&509&521&523&541&547&557&563&569&571&577&587&593&599&601&607&613&617&619&631&641&643&647&653&659&661&673&677&683&691&701&709&719&727&733&739&743&751&757&761&769&773&787&797&809&811&821&823&827&829&839&853&857&859&863&877&881&883&887&907&911&919&929&937&941&947&953&967&971&977&983&991&997
but not working in hackerrank compiler question is "Print Prime Numbers"

There's no problem in your code to produce the desired string except <br>i NUMBER;
Just comment out that piece in the declaration section as below :
DECLARE
n NUMBER; -- <br>i NUMBER;
pr NUMBER;
Here's a Demo for it.

Related

Convert Binary's 2's compliment to decimal in oracle SQL

I have a sample number in a column of oracle table which is binary's 2's complimanet -
e.g 0110001000110111
I want to convert this to normal decimal number in 2's compliment.
Expected output-
Reference link - https://www.rapidtables.com/convert/number/decimal-to-binary.html
You can loop as applying powers of 2 while multiplying by each bit(0 or 1) starting from the right end of your presented value such as
SET SERVEROUTPUT ON
DECLARE
bin_nr VARCHAR2(100) := '0110001000110';
dec_nr NUMBER;
BEGIN
FOR i IN 1..LENGTH(bin_nr)
LOOP
dec_nr := NVL(dec_nr,0) + SUBSTR(bin_nr,-i,1)*(2**(i-1));
END LOOP;
DBMS_OUTPUT.PUT_LINE(dec_nr);
END;
/
which results 3142 as the decimal value.
Demo
For 2s compliment, the most-significant bit represents the sign bit and if that is 1 then you have a negative number:
DECLARE
bin_nr VARCHAR2(100) := '1111001110111010';
sign PLS_INTEGER;
dec_nr PLS_INTEGER;
BEGIN
IF SUBSTR(bin_nr, 1, 1) = '1' THEN
bin_nr := TRANSLATE(bin_nr, '01', '10');
sign := -1;
dec_nr := 1;
ELSE
sign := 1;
dec_nr := 0;
END IF;
FOR i IN 1 .. LENGTH(bin_nr) LOOP
IF SUBSTR(bin_nr, -i, 1) = '1' THEN
dec_nr := dec_nr + POWER(2, i-1);
END IF;
END LOOP;
dec_nr := dec_nr * sign;
DBMS_OUTPUT.PUT_LINE(dec_nr);
END;
/
Outputs -3142
If you are expecting an N-bit binary number as the input (for example, the link in the question expects a 16-bit binary number as an input for 2s compliment) then you should LPAD with zeroes if you have fewer than that many bits.
db<>fiddle here

PLS-00103: Encountered the symbol "+" when expecting one of the following: (

declare
i number;
sum number;
begin
i:=1;
sum:=0;
for i in 1..100 loop
if MOD(i,2) != 0 then
sum:= sum + i;
dbms_output.put_line(i);
end if;
end loop;
dbms_output.Put_line(sum);
end;
sum is a reserved word, reserved for built-in function. Rename variable to v_sum (for example).
SQL> set serveroutput on
SQL>
SQL> DECLARE
2 v_sum NUMBER;
3 BEGIN
4 v_sum := 0;
5 FOR i IN 1 .. 100 LOOP
6 IF MOD (i, 2) != 0 THEN
7 v_sum := v_sum + i;
8 -- DBMS_OUTPUT.put_line (i);
9 END IF;
10 END LOOP;
11 DBMS_OUTPUT.Put_line (v_sum);
12 END;
13 /
2500
PL/SQL procedure successfully completed.
SQL>

Write PL/SQL code to generate Armstrong number from 1 to 500

I am getting output as a = 1. I have taken a for loop from 1 to 500 and while loops inside the outer for loop.
declare
n number;
s number:=0;
r number;
len number;
m number;
begin
for a in 1..500 loop
m:=a;
n:=a;
len:=length(to_char(n));
while(n>0) loop
r:=mod(n,10);
s:=s+power(r,len);
n:=trunc(n/10);
end loop;
if m=s then
dbms_output.put_line('a='||to_char(a)');
end if;
end loop;
end;
How about this?
substr splits i to 3 separate digits
nvl is here to avoid adding null value if those digits don't exist (yet)
power function calculates i's cube
display i if it is equal to r (as "result")
SQL> declare
2 r number;
3 begin
4 for i in 1 .. 500 loop
5 r := power(to_number(substr(to_char(i), 1, 1)), 3) +
6 nvl(power(to_number(substr(to_char(i), 2, 1)), 3), 0) +
7 nvl(power(to_number(substr(to_char(i), 3, 1)), 3), 0);
8
9 if r = i then
10 dbms_output.put_line(i);
11 end if;
12 end loop;
13 end;
14 /
1
153
370
371
407
PL/SQL procedure successfully completed.
SQL>
You never reset s and you do not need the final IF statement (unless you are only interested in the Armstrong numbers which equal the original number):
declare
n number;
s number:=0;
r number;
len number;
m number;
begin
for a in 1..500 loop
m:=a;
n:=a;
s:=0; -- Reset s for each loop
len:=length(to_char(n));
while(n>0) loop
r:=mod(n,10);
s:=s+power(r,len);
n:=trunc(n/10);
end loop;
dbms_output.put_line(a || '=' || s); -- Output values for every loop.
end loop;
end;
/
db<>fiddle here

Reading two dimensional pl/sql array

I am able to insert values but failed to retrieve values. Thanks in anticipation.
declare
type type1 is table of number;
type data_type is table of type1;
y data_type;
begin
y := data_type();
y.extend(100);
for i in 1..100 loop
y(i) := type1();
y(i).extend(100);
for j in 1..100 loop
y(i)(j) := i+j;
end loop;
end loop;
end;
If I understand well, you need a way to scan your arrays;
this could be a way:
declare
type type1 is table of number;
type data_type is table of type1;
y data_type;
k number := 2;
begin
y := data_type();
y.extend(k);
for i in 1..k loop
y(i) := type1();
y(i).extend(k);
for j in 1..k loop
y(i)(j) := i+j;
end loop;
end loop;
-- scanning
for i in y.first .. y.last loop
for j in y(i).first .. y(i).last loop
dbms_output.put_line('Y(' || i || ')(' || j || ') = ' || y(i)(j));
end loop;
end loop;
end;
the result:
Y(1)(1) = 2
Y(1)(2) = 3
Y(2)(1) = 3
Y(2)(2) = 4

factorial of a number in pl/sql

The following pl/sql program generates an error on execution on line the sum :=temp*sum; encountered symbol ; when expecting ( . Please explain my mistake.
declare
n number;
temp number;
sum number := 1;
begin
n := &n;
temp := n;
while temp>0 loop
sum := temp*sum;
temp := temp-1;
end loop;
dbms_output.put_line('Factorial of '||n||' is '||sum);
end;
/
Maybe not the answer to your question, but there is no need for PL/SQL here:
select round(exp(sum(ln(level))))
from dual
connect by level <= 5;
where 5 is your number (5!).
Additionally, if you like to operate faster in PL/SQL use pls_integer instead of number.
UPDATE
So according to comments I felt free to test:
create or replace package test_ is
function by_query(num number) return number deterministic;
function by_plsql(num number) return number deterministic;
end test_;
/
create or replace package body test_ is
function by_query(num number) return number deterministic
is
res number;
begin
select round(exp(sum(ln(level))))
into res
from dual
connect by level <= num;
return res;
end;
function by_plsql(num number) return number deterministic
is
n number := 0;
begin
for i in 1..num loop
n := n + ln(i);
end loop;
return round(exp(n));
end;
end test_;
So there are two functions with different content. Test query:
declare
dummy number;
begin
for i in 1..10000 loop
dummy := test_.by_query(5);
end loop;
end;
0.094 sec.
declare
dummy number;
begin
for i in 1..10000 loop
dummy := test_.by_plsql(5);
end loop;
end;
0.094 sec.
You'll say I am cheater and using deterministic keyword but here it is obvious and is needed by logic. If I remove it, the same scripts are working 1.7 sec vs 1.3 sec, so procedure is only a bit faster, there is no even double-win in performance. The totally opposite effect you will get if you use the function in a query so it is a fair trade.
Sum is reserved word in sql. Change variable name like
declare
n number;
temp number;
sum_ number := 1;
begin
n := &n;
temp := n;
while temp>0 loop
sum_ := temp*sum_;
temp := temp-1;
end loop;
dbms_output.put_line('Factorial of '||n||' is '||sum_);
end;
/
declare
n number;
i number;
sum_of_log_10s number;
exponent number;
base number;
begin
n := &n;
i := 1;
sum_of_log_10s := 0;
while i <= n loop
-- do stuff
sum_of_log_10s := sum_of_log_10s + log(10,i);
i := i + 1;
end loop;
dbms_output.put_line('sum of logs = '||sum_of_log_10s);
exponent := floor(sum_of_log_10s);
base := power(10,sum_of_log_10s - exponent);
dbms_output.put_line(n||'! = '||base||' x 10^'||exponent);
end;
I came up with this code that I like even better than #smnbbrv's answer. It's a great way to check the speed of a machine. I've been using a variation of this since my Atari 800
ALTER SESSION FORCE PARALLEL DDL PARALLEL 16;
ALTER SESSION FORCE PARALLEL DML PARALLEL 16;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 16;
with t as (
select /*+materialize*/
rownum i
from dual connect by rownum < 100000 -- put number to calculate n! here
)
,t1 as (
select /*+parallel(t,16)*/ /*+materialize*/
sum(log(10,i)) logsum
from t
)
select
trunc(power(10,(mod(logsum,1))),3) ||' x 10^'||trim(to_char(floor(logsum),'999,999,999,999')) factorial
-- logsum
from t1
;
-- returns 2.824 x 10^456,568
Here is the simple code for finding factorial of number at run time...
declare
-- it gives the final answer after computation
fac number :=1;
-- given number n
-- taking input from user
n number := &1;
-- start block
begin
-- start while loop
while n > 0 loop
-- multiple with n and decrease n's value
fac:=n*fac;
--dbms_output.put(n||'*');
n:=n-1;
end loop;
-- end loop
-- print result of fac
dbms_output.put_line(fac);
-- end the begin block
end;

Resources