Actual for "item" must be a variable - Ada - ada

procedure Summera(Int1: in Integer;
Int2: in Integer;
Summa: out Integer) is
begin
Put("Mata in ett heltal: ");
48 Get(Int1);
Put("Mata in ett heltal: ");
50 Get(Int2);
Summa:= Int1 + Int2;
Put("Du matade in heltalet: ");
Put(Int1, Width=>0);
Put(" och heltalet: ");
Put(Int2, Width=>0);
Put(" och summan blev ");
end Summera;
I know there is something wrong but not really what. on the lines 48 and 50 which are I get the error message "actual for item must be a variable." I am not allowed to put the string/text outside of the "subprogram" bit I have no idea how to make this work.
Why do I get this error messeage?
after begin I have this
Int1, Int2: Integer;
Summa: Integer;
begin
Summera(Int1, Int2, Summa);
Put(Summa);
end program;

The parameters
Int1: in Integer;
Int2: in Integer;
are in-parameters, ie. constants inside the procedure, whereas Get expects a variable in order to store the result. Maybe you meant for them to be local variables instead? Or in out parameters?

Int1 and Int2 do not belong as parameters to the procedure Summera. Modify the procedure as follows:
procedure Summera(Summa: out Integer) is
Int1 : Integer;
Int2 : Integer;
begin
Put("Mata in ett heltal: ");
Get(Int1);
Put("Mata in ett heltal: ");
Get(Int2);
Summa:= Int1 + Int2;
Put("Du matade in heltalet: ");
Put(Int1, Width=>0);
Put(" och heltalet: ");
Put(Int2, Width=>0);
Put(" och summan blev ");
end Summera;
Int1 and Int2 are local variables of procedure Summera. Your version cannot modify the values of Int1 and Int2.
If you want to modify the values of Int1 and Int2 and see those modified values in your main procedure you will want to declare the values to be OUT parameters.
procedure Summera(Int1: out Integer; Int2: out Integer; Summa: out Integer) is
begin
Put("Mata in ett heltal: ");
Get(Int1);
Put("Mata in ett heltal: ");
Get(Int2);
Summa:= Int1 + Int2;
Put("Du matade in heltalet: ");
Put(Int1, Width=>0);
Put(" och heltalet: ");
Put(Int2, Width=>0);
Put(" och summan blev ");
end Summera;
OUT parameter mode is used when your procedure does not care what the initial value of the parameter is when it is passed to the procedure, but it must provide a value for the parameters within the procedure.

Related

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)

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.

Ada Constraint_error invalid enumeration value

Im so close to finishing this lab I can taste it. I realize my Ada code is very novice as I just began working with it this semester. The error seems to persist at location 19 when I try to use 'put' on mainStk at said location. Im wondering why i cannot get access to mainStk(19) as this is what seems to be the issue.
This is the error code
raised CONSTRAINT_ERROR : mainStk.Input_IO.Put: invalid enumeration value [2018-03-07 18:46:16] process exited with status 1, elapsed time: 05.40s
This is the .adb its appearing in.
with Ada.Text_IO;
use Ada.Text_IO;
package body ProcsAndFuncs is
Base: array(1..N+1) of integer; --self descriptive arrays to maintain stacks
Top: array(1..N) of integer;
Old_Top: array(1..N) of integer;
mainStk: array(LowerB..UpperB) of Input;
package Int_IO is new Ada.Text_IO.Integer_IO(Integer);
use Int_IO; --IO routine for my integers
package Input_IO is new Ada.TExt_IO.Enumeration_IO(Input);
use Input_IO; --IO routine for Data
procedure ReA_Move(Snum: integer; Data: Input) is --procedure follows ReA1-ReA6 in notes (pg 22-23)
New_Base : array (1..N+1) of integer; --following variables from notes being declared and initalized
Growth : array (1..N) of Integer;
Alpha, Beta, Sig, Tau: float:= 0.00;
Growth_All: float:= 0.87; --divide 87% avail memory based on growth
Equal_All: float:= 0.13; --divide 13% avail memory equally
TotalInc, Avail, Delt: integer:= 0;
min_space: Integer:= 1;
J: integer;
begin
Avail:= M-L0; --beginning ReA1 from notes (p.22)
J:= N;
new_line;
Put("Contents of Old Top(J), Top(J), and Base(J) before repacking as requested:");
new_line;
for i in 1..N loop
put("old top("); put(i,1); put(")= ");
put(old_top(i),1);
put(".. Top("); put(i,1); put(")= ");
put(top(i),1);
put(".. Base("); put(i,1); put(")= ");
put(base(i),1);
new_line;
end loop;
while J>0 loop --ReA1 from notes
Avail:= Avail-(Top(j)-Base(j));
if top(j) > old_top(j) then
Growth(j):= Top(j)-old_top(j);
TotalInc:= TotalInc+Growth(j);
else
growth(j) := 0;
end if;
J:= J-1;
end loop;
if Avail < (Min_Space - 1) then --ReA2 from notes
Put("Insufficient memory for re-packing to occur, terminating.");
raise Program_Error;
end if;
growth_All:= 1.0-Equal_All; --ReA3 from notes
Alpha:= (Equal_All * Float(Avail)) / float(N);
beta:= (Growth_All * Float(Avail)) / float(totalinc); --ReA4 from notes
new_base(1):= base(1); --ReA5 from notes
Sig:= 0.0;
for j in 2..N loop
tau:= sig+alpha+(float(Growth(j-1)) * Beta);
new_base(j):=new_base(j-1)+(top(j-1)-base(j-1))+Integer(float'Floor(tau))-Integer(float'Floor(sig));
sig:= tau;
end loop;
Top(Snum):= Top(Snum)-1; --ReA6
for j in 2..N loop --MoA1 from notes
if new_base(j) < base(j) then
delt:= base(j)-new_base(j);
for l in integer range(base(j) + 2)..(top(j)) loop
mainStk(l-delt):= mainStk(l);
end loop;
base(j):= new_base(j);
top(j):= top(j)-delt;
end if;
end loop;
for j in 2 .. N loop --MoA2 from notes
if new_base(j) > Base(j) then
delt:= new_base(j)-base(j);
for l in (Top(j)-1)..(base(j)+1) loop
mainStk(l+delt):= mainStk(l);
end loop;
base(j):= new_base(j);
top(j):= top(j)+delt;
end if;
end loop;
top(Snum):= Top(Snum)+1; --jumping back to ReA6
mainStk(Top(Snum)):= data;
new_line;
Put("Bases and tops after repack as requested:"); new_line;
for J in 1..N loop --prepare for potential overflow
Put("Base("); put(j,1); put(")= ");
put(base(j),1);
Put(", Top("); put(j,1); put(")= ");
put(top(j),1);
new_line;
old_top(J):= Top(J);
end loop;
new_line;
put("continuing tansactions..");
end ReA_move;
procedure output is --declaration for procedure 'output' (procedures return no value)
begin
new_line;
new_line;
for i in 1..N loop --outputs conents of each transaction as requested
put("Stack #:");
put(i); new_line;
for j in base(i)+1..top(i) loop
if j < base(i+1) then
put(" Loc[" & integer'image(j) & " ]: ");
put(mainStk(j)); --put problem?
new_line;
end if;
end loop;
end loop;
end output;
procedure Push(Stack:Integer; Data:Input) is --procedure since no value returned
begin
top(Stack):= top(Stack)+1; --Insertion into stack from notes
if Top(Stack) > Base(Stack+1) then
new_line;
put("Overflow occured, calling Reallocate"); new_line; --report overflow
ReA_move(stack, data); --determine if additional space can be made
else
mainStk(Top(Stack)):= data; --insert data into stack
output;
end if;
end Push;
function Pop(Stack: Integer) return Input is --function used to return value
data: Input;
begin
if top(stack) = base(stack) then --implement Pop as in deletion from stack pg 21
put("Reporting underflow..");
return empty;
else
data:= mainStk(top(stack));
top(stack):= top(stack)-1;
return (mainStk(top(Stack)));
end if;
end Pop;
begin
Put("Initial Tops and Bases: ");
for j in 1..N loop --loop equally initializes Tops & Bases prior to transactions
base(j):= Integer(Float'Floor(((Float(j) - 1.0) / Float(N) * Float(M - L0)) + Float(L0)));
Top(j):= Base(j);
old_top(j):= top(j);
new_line;
Put("Base(");
put(j,1);
put(") = ");
put("Top(");
put(j,1);
put(")= ");
put(top(j),1);
end loop;
new_line;
put("Base(5)= 27");
end;
This is my generic which may or may not be needed.
generic
N:integer;
M:integer;
L0:integer;
LowerB:integer;
UpperB:integer;
package ProcsAndFuncs is
type Input is (Zhou, Wei, Burris, Shashidhar, Deering, An, Lester, Yang, Smith, Arcos,
Rabieh, Song, Cho, Varol, Karabiyik, Cooper, McGuire, Najar, Hope, Pray, NoHope, empty);
procedure ReA_move(Snum : in integer; Data : Input);
procedure push(stack : integer; Data : Input);
function pop(stack : Integer) return Input;
procedure output;
end;

Ada - Prime factorization of numbers

My first homework assignment in Ada is to create a program that states whether a number is composite or prime, display its factors, and then indicate its prime factorization. So for example the number 12 would be composite, 1,2,3,4,6,12. Prime factorization 2 * 2 * 3.
I'm mostly done, my code indicates if it's a composite number, and all the factors, just not sure how to code the actual prime factorization part where it would display the 2 * 2 * 3. I have done the rest, but could use some insight as to what code would be the best to proceed.
WITH Ada.Text_IO, Ada.Integer_Text_IO;
USE Ada.Text_IO, Ada.Integer_Text_IO;
PROCEDURE program_one IS
input: File_Type := Ada.Text_IO.Standard_Input;
Value: Integer;
AbsValue: Natural;
factorCount: Integer := 0;
begin
--Open(input, In_File);
WHILE NOT End_Of_File(input) LOOP
IF End_Of_Line(input) THEN
Skip_Line(input);
ELSE
Get(Input, Value);
Put(Value, Width => 1);
absValue := abs Value;
Put(": Positive Factors are: ");
FOR I IN Integer RANGE 1 .. absValue LOOP
IF absValue mod I = 0 THEN
Put(I, Width => 1);
factorCount := factorCount + 1;
IF I /= absValue THEN
Put(", ");
END IF;
END IF;
END LOOP;
New_Line;
IF FactorCount = 2 THEN
Put(Value, 6);
Put(" is prime.");
END IF;
IF FactorCount = 1 OR FactorCount = 0 THEN
Put(Value, 6);
Put(" is neither prime nor composite");
END IF;
IF FactorCount > 2 THEN
Put(Value, 6);
Put(" is composite");
END IF;
factorCount := 0;
New_Line;
END IF;
END LOOP;
Close(Input);
end program_one;

Recursive permutation

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.

Resources