Recursive permutation - recursion

So I'm trying to permute all possible n digit long numbers out of x long array/set of elements. I've come up with a code that does that, however the digits are the same, how do I prevent that from happening. Here's my come(Pascal):
program Noname10;
var stop : boolean;
A : array[1..100] of integer;
function check( n : integer ) : boolean;
begin
if n = 343 // sets the limit when to stop.
then check := true
else check := false;
end;
procedure permute(p,result : integer);
var i : integer;
begin
if not stop
then if p = 0 then
begin
WriteLn(result);
if check(result)
then stop := true
end
else for i := 1 to 9 do
begin
permute(p - 1, 10*result+i);
end;
end;
begin
stop := false;
permute(3,0);
readln;
end.

Here is the code in Prolog
permutate(As,[B|Cs]) :- select(B, As, Bs), permutate(Bs, Cs).
select(A, [A|As], As).
select(A, [B|Bs], [B|Cs]) :- select(A, Bs, Cs).
?- permutate([a,b,c], P).
Pascal is much harder.
Here is an usefull algorithm, you might want to use. But it is not tested, so you have to debug it yourself. So you have to know how the algorithm works.
The Bell Permutation algorithm: http://programminggeeks.com/bell-algorithm-for-permutation/
procedure permutate(var numbers: array [1..100] of integer; size: integer;
var pos, dir: integer)
begin
if pos >= size then
begin
dir = -1 * dir;
swap(numbers, 1, 2);
end
else if pos < 1 then
begin
dir = -1 * dir;
swap(numbers, size-1, size);
end
else
begin
swap(numbers, pos, pos+1);
end;
pos = pos + dir;
end;
begin
var a, b: integer;
a = 1; b = 1;
while true do
begin
permutate(A, 5, a, b);
printArray(A, 5);
end;
end.

Related

Factorial of a number in pl/sql (Not showing the correct output)

I have written down a code in pl/sql but output is not showing
having trouble with this code.
declare
num number(20):= 0;
val number(10):= 5;
temp number(10):= 0;
function factorial (n1 in number)
return number
is
fact number(10):= 1;
begin
temp:= n1;
loop
if fact <=0 then
exit;
else
fact := fact *temp;
temp:=temp-1;
end if;
end loop;
return fact;
end;
begin
num:= factorial(val);
dbms_output.put_line('Factorial of ' ||val||' is '||num);
end;
Output:- Factorial of 5 is 0
The line:
if fact <=0 then
should be:
if temp <=0 then
You don't really need the 'else' part, because the 'if' exits the loop anyway; so you could do:
loop
if temp <=0 then
exit;
end if;
fact := fact *temp;
temp:=temp-1;
end loop;
Or avoid the explicit check by using a while loop:
while temp > 0 loop
fact := fact *temp;
temp:=temp-1;
end loop;
... etc.
db<>fiddle
You are checking fact <= 0 rather than checking temp <= 0 and you should also declare the temp variable locally to the function:
declare
val number(10):= 5;
function factorial (n1 in number)
return number
is
fact number(10) := 1;
temp number(10) := n1;
begin
loop
if temp <=0 then
exit;
else
fact := fact *temp;
temp:=temp-1;
end if;
end loop;
return fact;
end;
begin
dbms_output.put_line('Factorial of ' ||val||' is '|| factorial(val) );
end;
/
Or, more simply:
declare
val number(10):= 5;
function factorial (n1 in number)
return number
is
fact number(10) := 1;
BEGIN
FOR temp IN 2 .. n1
LOOP
fact := fact *temp;
END LOOP;
RETURN fact;
END;
begin
dbms_output.put_line('Factorial of ' ||val||' is '|| factorial(val) );
end;
/
db<>fiddle here

First two counters are never increased in dice rolling application

I am writing a program that rolls two dice and uses an array of counters to show how many times each total is shown. My code compiles fine and does run but for some reason the first two counters are never increased, and seems to print in numeric ascending order - which to me sounds like a problem with my random number function. But I cannot quite see where I have gone wrong. It also never iterates the correct amount of times, about half in fact. Here is my code.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
-- procedure main - begins program execution
procedure main is
dice1, dice2, diceTotal : Integer;
type Count_Array is array(1 .. 11) of Integer;
intArray : Count_Array;
-- function returnRand - produces a random number and returns it
function returnRand return Integer is
type magicNumber is new Integer range 2 .. 12;
package Rand_Number is new Ada.Numerics.Discrete_Random(magicNumber);
use Rand_Number;
theNumber : magicNumber;
g : Generator;
begin
Reset(g);
theNumber := Random(g);
return Integer(theNumber);
end returnRand;
-- procedure rollDice - rolls two dice 36000 times and tallys the totals
procedure rollDice(dice1 : out Integer; dice2 : out Integer;
diceTotal : out Integer; intArray : in out Count_Array) is
begin
for I in 1 .. 36000 loop
dice1 := returnRand;
dice2 := returnRand;
diceTotal := dice1 + dice2;
if diceTotal = 2 then
intArray(1) := intArray(1) + 1;
elsif diceTotal = 3 then
intArray(2) := intArray(2) + 1;
elsif diceTotal = 4 then
intArray(3) := intArray(3) + 1;
elsif diceTotal = 5 then
intArray(4) := intArray(4) + 1;
elsif diceTotal = 6 then
intArray(5) := intArray(5) + 1;
elsif diceTotal = 7 then
intArray(6) := intArray(6) + 1;
elsif diceTotal = 8 then
intArray(7) := intArray(7) + 1;
elsif diceTotal = 9 then
intArray(8) := intArray(8) + 1;
elsif diceTotal = 10 then
intArray(9) := intArray(9) + 1;
elsif diceTotal = 11 then
intArray(10) := intArray(10) + 1;
elsif diceTotal = 12 then
intArray(11) := intArray(11) + 1;
end if;
end loop;
end rollDice;
-- procedure printResults - prints out the totals of each dice throw
procedure printResults(intArray : in Count_Array) is
begin
Put_Line("Dice Total Tally");
for I in Count_Array'Range loop
-- Set_Col(2);
-- Put(integer'image(I));
-- Set_Col(23);
Put(integer'image(intArray(I)));
New_Line;
end loop;
end printResults;
begin
New_Line;
intArray := (0,0,0,0,0,0,0,0,0,0,0);
rollDice(dice1, dice2, diceTotal, intArray);
printResults(intArray);
New_Line;
end main;
You roll two D11s (range 2..12), not D6s, so when you add them together, you get a range of 4..24 instead of the expected 2..12.
If you used the type system to model the problem, this would have been detected:
type Count_Array is array(2 .. 12) of Integer;
and then your if..elsif construct could be just:
intArray(diceTotal) := intArray(diceTotal) + 1;
Change your magicNumber to a 1..6 range to roll a D6 instead.
Also, there's no need to reset the Generator every time you roll a die. Once is sufficient.
Edit:
You could also go much further with the type system, and do something like this:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Main is
Number_Of_Dice : constant := 2;
type Die_Range is new Positive range 1 .. 6;
subtype Sums_Range is Die_Range'Base
range Number_Of_Dice*Die_Range'First..Number_Of_Dice*Die_Range'Last;
type Count_Array is array(Sums_Range) of Natural;
package Random_Die is new Ada.Numerics.Discrete_Random(Die_Range);
Die : Random_Die.Generator;
function Roll(Die : Random_Die.Generator) return Die_Range
renames Random_Die.Random;
procedure Roll_Dice(Sums : in out Count_Array) is
Dice_Total : Sums_Range'Base;
begin
for I in 1 .. 36_000 loop
Dice_Total := Roll(Die);
for I in 1..Number_Of_Dice-1 loop
Dice_Total := Dice_Total + Roll(Die);
end loop;
Sums(Dice_Total) := Sums(Dice_Total) + 1;
end loop;
end Roll_Dice;
procedure Print_Results(Sums : in Count_Array) is
begin
Put_Line("Dice Total Tally");
for I in Sums'Range loop
Put(Sums(I)'Image);
New_Line;
end loop;
end Print_Results;
Sums : Count_Array;
begin
Random_Die.Reset(Die);
New_Line;
Sums := (others => 0);
Roll_Dice(Sums);
Print_Results(Sums);
New_Line;
end Main;
Notice how easy this code will be to maintain when the requirements change, for example the number of dice cast per roll, or the type of dice (D4, D6, D8, D12, etc)

Why it is oveflow in contador in ada?

I dont know why the prove is error at the overflow in the variable contador. I need help.
contador: Integer;
J: Integer;
function noPrimos (lista : My_Array) return Boolean
with
Global => contador,
--Depends => ...,
Pre => True and contador < Integer'Last,
Post => (noPrimos'Result = True or noPrimos'Result = False);
FILE ADB
function noPrimos (lista : My_Array) return Boolean is
contador: Integer;
begin
for I in lista'Range loop
contador:= 0;
if lista(I) /= 1 then
for J in 1.. lista(I) loop
if lista(I) rem J = 0 then
contador := contador + 1;
end if;
end loop;
if contador <= 2 then
return false;
end if;
else
return true;
end if;
pragma Loop_Variant(Increases => I);
end loop;
return true;
end noPrimos;
The problem is the overflow the result:
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
15:40: medium: overflow check might fail (e.g. when contador = 2147483647)
47:40: medium: overflow check might fail (e.g. when contador = 0)
First of all, I assume that the function noPrimos will return True only if the list lista does not contain any primes. That being said, I'm a little bit puzzled by some aspects of the code snippet:
The type definition of My_Array is missing.
The role of the global instance of contador (english: counter) is not clear from the given code snippet. By writing Global=> contador, you state that the global variable contador will be read by the function noPrimos (see also here), but that doesn't happen because the local instance of contador shadows the global instance of contador.
The reason for the variable J being defined globally is not clear, you can omit it.
The precondition True (on the left side of the Boolean operator and) is trivial and can be omitted.
The postcondition states that the result of noPrimos can either be True or False. This is trivial as noPrimos returns a boolean and can therefore be omitted. The postcondition should state the function's expected result given its inputs.
The loop variant pragma Loop_Variant(Increases => I); is trivial as the variable I will increase by the definition of the for-loop. Hence the loop variant can be omitted.
Below is an example of a function No_Primes that searches the given list L for primes and returns True if none are found. It proves in GNAT CE 2019:
primes.ads (spec)
package Primes with SPARK_Mode is
type List is
array (Natural range <>) of Positive;
--
-- Returns True if N is a prime number (or False otherwise).
--
function Is_Prime (N : Positive) return Boolean
with
Global => null,
Post => Is_Prime'Result =
(if N = 1 then False
else (for all I in 2 .. N - 1 => N rem I /= 0));
--
-- Returns True if list L does not contain any prime numbers (or False otherwise).
--
function No_Primes (L : List) return Boolean
with
Global => null,
Post => No_Primes'Result =
(for all I in L'Range => Is_Prime (L (I)) = False);
end Primes;
primes.adb (body)
package body Primes with SPARK_Mode is
--------------
-- Is_Prime --
--------------
function Is_Prime (N : Positive) return Boolean is
begin
if N = 1 then
return False;
else
for I in 2 .. N - 1 loop
if N rem I = 0 then
return False;
end if;
pragma Loop_Invariant
(for all J in 2 .. I => N rem J /= 0);
end loop;
end if;
return True;
end Is_Prime;
---------------
-- No_Primes --
---------------
function No_Primes (L : List) return Boolean is
begin
for I in L'Range loop
if Is_Prime (L (I)) then
return False;
end if;
pragma Loop_Invariant
(for all J in L'First .. I => Is_Prime (L (J)) = False);
end loop;
return True;
end No_Primes;
end Primes;
A small test program (main.adb)
with Ada.Text_IO; use Ada.Text_IO;
with Primes; use Primes;
procedure Main is
-- Some test vectors.
L1 : List := (1 => 1); -- Expect TRUE : 1 is not a prime.
L2 : List := (1, 2, 3, 5, 7); -- Expect FALSE : All are prime except 1.
L3 : List := (2, 3, 5, 7); -- Expect FALSE : All are prime.
L4 : List := (1, 4, 6, 8, 9); -- Expect TRUE : None are prime.
L5 : List := (4, 6, 8, 9); -- Expect TRUE : None are prime.
L6 : List := (3, 4, 5); -- Expect FALSE : 3 and 5 are prime.
begin
Put_Line ("No_Primes (L1) = " & Boolean'Image (No_Primes (L1)));
Put_Line ("No_Primes (L2) = " & Boolean'Image (No_Primes (L2)));
Put_Line ("No_Primes (L3) = " & Boolean'Image (No_Primes (L3)));
Put_Line ("No_Primes (L4) = " & Boolean'Image (No_Primes (L4)));
Put_Line ("No_Primes (L5) = " & Boolean'Image (No_Primes (L5)));
Put_Line ("No_Primes (L6) = " & Boolean'Image (No_Primes (L6)));
end Main;
yields
No_Primes (L1) = TRUE
No_Primes (L2) = FALSE
No_Primes (L3) = FALSE
No_Primes (L4) = TRUE
No_Primes (L5) = TRUE
No_Primes (L6) = FALSE

Insert an element to linked list with the help of recursion

This Pascal code inserts a new element to a linked list with the help of "while loop":
program linked_list;
type
pointer_typ = ^record_2;
record_2 = record
data: integer;
next: pointer_typ;
end;
procedure Push_int(var p: pointer_typ; x: integer);
var
temp: pointer_typ;
begin
new(temp);
temp^.data := x;
temp^.next := p;
p := temp
end;
var
first: pointer_typ;
x: integer;
begin
first := nil;
while not Seekeof do begin
read(x);
Push_int(first, x)
end;
end.
Can you help with making a procedure which inserts a new element to linked list but with the help of recursion (not with while loop)?
I tried and got wrong results (for example, the code below returns values in "queue order", but not in "stack order" as I'd like):
program linked_list;
type
pointer_typ = ^record_2;
record_2 = record
data: integer;
next: pointer_typ;
end;
procedure Push_int(var p: pointer_typ);
var
temp: pointer_typ;
x: integer;
begin
read(x);
new(temp);
temp^.data := x;
temp^.next := p;
p := temp;
if Seekeof then
exit
else
Push_int(p^.next)
end;
var
first: pointer_typ;
begin
first := nil;
Push_int(first);
end.
Thank you.
Seems, this one works correct:
program linked_list;
type
pointer_typ = ^record_2;
record_2 = record
data: integer;
next: pointer_typ;
end;
procedure Push_int(var p: pointer_typ; x: integer);
var
temp: pointer_typ;
begin
new(temp);
temp^.data := x;
temp^.next := p;
p := temp;
if Seekeof then
exit
else begin
read(x);
Push_int(p, x)
end;
end;
var
first: pointer_typ;
x: integer;
begin
first := nil;
read(x);
Push_int(first, x)
end.

How can I write this algorithm using iteration?

How can I write this algorithm using iteration?
function generate(num1:byval)
if num1 > 10 then
return 10
else
return num1 + (generate(num1 + 1) DIV 2)
endif
endfunction
So it's not straight forward so I start by doing some grunt work:
n result
11.. 10
10 10
9 9 + 10/2
8 8 + (9 + 10/2)/2
7 7 + (8 + (9 + 10/2)/2)/2
This looks like a pattern.. While the recursive version started on the input and went upwards it's easy to see that by starting at 10 and going downwards one can simply update the accumulator by halving the value and adding the current value.
This can easily be implemented using a helper:
procedure generate(num : integer) : integer
begin
generate := generateHelper(10, num, 0)
end
procedure generateHelper(cur : integer, num: integer, acc : integer) : integer
begin
if cur = num then
generateHelper := cur + acc/2;
else
generateHelper := generateHelper(cur - 1, num, acc/2 + cur);
end
Or by using a loop:
procedure generate(num : integer) : integer
var cur, acc : integer;
begin
for cur := 10 downto cur do
acc := acc / 2 + cur;
generate := acc;
end
If you work out some values for the function…
f(10) = 10
f(9) = 9+f(10)/2 = 9+10/2 = 14
f(8) = 8+f(9)/2 = 8+14/2 = 15
…
You will get a sense that you could repeatedly apply the same formula to a value in a loop. You see if you start from 10, you divide by 2 and add 9, then divide by 2 and add 8, and keep going until you reach the number given to the function. That would look something like this, e.g. in JavaScript:
function generate(n) {
let x = 10;
for(let i = 10; i > n; i--) {
x = i - 1 + x / 2;
}
return x;
}

Resources