obtaining a list of prime numbers in Ada - ada

I have made a program for obtaining a list of prime numbers in ADA and using the following online compiler:
https://rextester.com/l/ada_online_compiler
My code is the following:
--GNAT 8.3.0
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO;
procedure prime is
function isPrime(n:in Integer) return Boolean is
begin
for i in 2..n loop
if n mod i=0 then
return False;
end if;
end loop;
return True;
end isPrime;
begin
for i in 1..100 loop
if isPrime(i)=True then
Ada.Text_IO.Put_Line(Integer'Image(i));
end if;
Ada.Text_IO.Put_Line(Integer'Image(i));
end loop;
end prime;
And instead of printing a list of primes it only print 1. I have program the same code in C and no problem at all.

Your for loop in isPrime() checks every value higher than one as "n mod n = 0" which will cause you to return false for every value higher than 1. Change the for loop condition to
for i in 2..(n-1) loop
and work from there

Expanding on Jere's approach, several simple primality tests will simplify the divisibility test in the isPrime loop:
The only even prime, 2, can be handled immediately:
if N = 2 then
return True;
end if;
All remaining even numbers can be eliminated:
if N mod 2 = 0 then
return False;
end if;
This leaves odd numbers in the range 3 .. √N to check:
for i in 3 .. Positive (Sqrt (Float (N))) loop
if N mod i = 0 then
…
end if;
end loop;

It is even better by defining a Prime_Number type containing prime numbers.
subtype Prime_Number is Positive range 2 .. Positive'Last with
Dynamic_Predicate => (for all I in 2 .. (Prime_Number / 2)
=> (Prime_Number mod I) /= 0);
Then, use the code segment below to print out all prime numbers between 2 .. 100 range.
for Index in Positive range 2 .. 100 loop
if Index in Prime_Number then
Put_Line ("Prime number: " & Index'Image);
end if;
end loop;

Related

fibonacci series program using functions in pl/sql

I've to create a function which print the Fibonacci series as its result. I've used a varray in the program below but it is giving me an error saying "PLS-00201: identifier 'ARRAY' must be declared" on line no. 2.
create function fibonacci7(x int)
return VARRAY
is
type fib IS VARRAY(25) OF VARCHAR(10);
a number(3):=1;
b number(3):=1;
c number(3);
i number(3):=1;
begin
while a<=n
loop
fib(i) := a;
c:=a+b;
a:=b;
b:=c;
i:=i+1;
end loop;
return codes_;
end ;
/
select fibonacci7(5) from dual;
I think this will do what you want. VARRAY's have a little different syntax than what you were using.
set serveroutput on size 1000000
create or replace type fibtype AS VARRAY(25) OF NUMBER;
/
create or replace function fibonacci7(n number)
return fibtype
is
fib fibtype := fibtype();
a number:=1;
b number:=1;
c number;
i number:=1;
begin
fib.extend(n);
while i<=n
loop
fib(i) := a;
c:=a+b;
a:=b;
b:=c;
i:=i+1;
end loop;
return fib;
end ;
/
declare
i number;
fib fibtype := fibtype();
begin
fib := fibonacci7(6);
for i in 1..fib.count loop
dbms_output.put_line(to_char(fib(i)));
end loop;
end;
/
Here is the output.
1
1
2
3
5
8
Bobby
p.s. Fixed to work with fib(6) and made array numbers

How to use recursion to add the product of two Integers together?

In this code, I am asking the user to input two integers (Index, Mindex) and then I display all the integers between 1..Index and 1..Mindex. What my problem is here that I do not know how to multiply the values of Integers in Index and Integers in `Mindex and then add up the product of these two together
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Add is
Index, Mindex : Integer;
procedure calc (Item : in Integer) is
New_Value : Integer;
begin
Put ("The value of the index is now");
Put (Item);
New_Line;
New_Value := (Item - 1);
if New_Value > 0 then
calc (New_Value);
end if;
end calc;
begin
Get (Index);
Get (Mindex);
calc (Index);
New_Line;
calc (Mindex);
end Add;
A factorial keeps chaining multiplication with each decreasing value: 5! = 5 * 4 * 3 * 2 * 1 = 120. In order to do the recursion, you'll need to have two cases inside your recursive function: If your value is above 1, then multiply that value with the next smallest number. That's the recursive part where you will call Factorial(N-1) inside of Factorial(N). Otherwise just return 1 (factorial of 0 is 1 mathematically, so both 1! and 0! equal 1).
The way this works in Ada is:
function Factorial(Value : Natural) return Natural is
begin
if Value > 1 then
-- Keep chaining the multiplication with recursion
return Value * Factorial(Value - 1);
else
-- No need to chain as the result is always 1
return 1;
end if;
end Factorial;
You can then call that Factorial function on each of your numbers and add the results.

generating prime numbers in pl/sql

Please tell me the problem in the code. I have written this code and its not working. Tell me the mistakes or if there is any other and easy method to generate prime numbers till 1000.
declare
i number;
prime number;
j number;
begin
for i in 2 .. 1000 loop
prime := 0;
for j in 2 .. i/2 loop
if mod(i,j)=0 then prime := 1
end if;
end loop;
if prime = 0 then dbms_output.put_line(i||'&');
end if;
end loop;
end;
You already have your answer (missing semicolon), but just for fun:
The i variable declared at the top is not used.
In theory j would be more efficient as a pls_integer (as i is implicitly). Possibly even a simple_integer, but then you'd need to restructure the loop to make i a simple_integer as well, and it's barely worth it for the tiny fraction of a second you might gain, if the compiler hasn't already optimised it.
You might as well exit the inner loop at the first match, rather than checking every single number.
prime would be more readable as a Boolean.
On the subject of readability, it is standard practice to align end loop under its opening loop statement.
I'm not seeing the point of appending & to every line of output.
This gives me:
declare
j pls_integer;
prime boolean;
begin
for i in 2 .. 1000 loop
prime := true;
for j in 2 .. i/2 loop
if mod(i,j) = 0 then
prime := false;
exit;
end if;
end loop;
if prime then
dbms_output.put_line(i);
end if;
end loop;
end;
You have missed one semicolon and try to put set server output on then run it
set serveroutput on
declare
i number;
prime number;
j number;
begin
for i in 2 .. 1000 loop
prime := 0;
for j in 2 .. i/2 loop
if mod(i,j)=0 then prime := 1;
end if;
end loop;
if prime = 0 then dbms_output.put_line(i||'&');
end if;
end loop;
end;
/

recursion using for do loop (pascal)

I'm trying to use the concept of recursion but using for do loop. However my program cannot do it. For example if I want the output for 4! the answer should be 24 but my output is 12. Can somebody please help me?
program pastYear;
var
n,i:integer;
function calculateFactorial ( A:integer):real;
begin
if A=0 then
calculateFactorial := 1.0
else
for i:= A downto 1 do
begin
j:= A-1;
calculateFactorial:= A*j;
end;
end;
begin
writeln( ' Please enter a number ');
readln ( n);
writeln ( calculateFactorial(n):2:2);
readln;
end.
There are several problems in your code.
First of all it doesn't compile because you are accessing the undefined variable j.
Calculating the factorial using a loop is the iterative way of doing it. You are looking for the recursive way.
What is a recursion? A recursive function calls itself. So in your case calculateFactorial needs a call to itself.
How is the factorial function declared?
In words:
The factorial of n is declared as
1 when n equals 0
the factorial of n-1 multiplied with n when n is greater than 0
So you see the definition of the factorial function is already recursive since it's referring to itself when n is greater than 0.
This can be adopted to Pascal code:
function Factorial(n: integer): integer;
begin
if n = 0 then
Result := 1
else if n > 0 then
Result := Factorial(n - 1) * n;
end;
No we can do a few optimizations:
The factorial function doesn't work with negative numbers. So we change the datatype from integer (which can represent negative numbers) to longword (which can represent only positive numbers).
The largest value that a longword can store is 4294967295 which is twice as big as a longint can store.
Now as we don't need to care about negative numbers we can reduce one if statement.
The result looks like this:
function Factorial(n: longword): longword;
begin
if n = 0 then
Result := 1
else
Result := Factorial(n - 1) * n;
end;

Pascal. Recursive function to count amount of odd numbers in the sequence

I need to write recursive function to count amount of odd numbers in the sequence
Here my initial code:
program OddNumbers;
{$APPTYPE CONSOLE}
uses
SysUtils;
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2=0)) then
begin
count:= count + 1;
GetOddNumbersAmount:=count;
end;
i:=i+1;
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i);
end;
var X: array[1..10] of integer;
i,amount: integer;
begin
writeln('Enter your sequence:');
for i:=1 to 10 do
read(X[i]);
amount:= GetOddNumbersAmount(X, 0, 1);
writeln('Amount of odd numbers: ', amount);
readln;
readln;
end.
When i type the sequence and press "enter", program closed without any errors and i can't see the result.
Also, i think my function isn't correct.
Can someone help with that code?
UPD:
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2<>0)) then
count:= count + 1;
if(i = 10) then
GetOddNumbersAmount:=count
else
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i+1);
end;
You don't provide an end of recursion, i.e., you always call your function GetOddNumbersAmount again, and your program never terminates. Thus, you get an array index error (or a stack overflow) and your program crashes.
Please note, that every recursion need a case where it terminates, i.e. does not call itself. In your case, it should return if there are no elements in the array left.
In addition, you are counting the even numbers, not the odd ones.
You passed a static array to a dynamic so the index get confused:
Allocat the array with
SetLength(X,10)
allocates an array of 10 integers, indexed 0 to 9.
Dynamic arrays are always integer-indexed, always starting from 0!
SetLength(X,10)
for it:=0 to 9 do begin
X[it]:= random(100);
And second if you know the length a loop has more advantages:
function GetEvenNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
for i:= 0 to length(X)-1 do
if((x[i] <> 0) and (x[i] mod 2=0)) then begin
inc(count);
//write(inttostr(X[i-1])+ ' ') :debug
end;
result:=count;
end;

Resources