Pascal: Got to subtract 1 from length to get right size - for-loop

I've got a piece of code like this:
for I := 0 to Self.EventQueue.Count do
Dispose(Self.EventQueue[I]);
It bugs out when the Count is 0, because it tries to Dispose a nonexisting element. When I change it to
for I := 0 to Self.EventQueue.Count-1 do
Dispose(Self.EventQueue[I]);
All works fine. Is there any elegant way to get around this or is this common practice?

This is absolutely normal behavior, and is documented in the help for every list and container class in Delphi/FreePascal. The reason is pretty clear - if you have three items in the list, and the first item is at index 0, then you have items 0, 1, 2 but a Count of 3, right?
for i := 0 to StringList.Count - 1 do // TStringList
for i := 0 to List.Count - 1 do // TList
for i := 0 to StringGrid1.ColCount do // TStringGrid
The alternative isn't as clear (and to me is worse to type):
for i := 0 to Pred(StringList.Count) do
Dynamic arrays start at index 0 as well.
var
IntArray: array of Integer;
i: Integer;
begin
SetLength(IntArray, 10);
for i := Low(IntArray) to High(IntArray) do // loop is 0..9
//
end;
The only things that aren't 0 based in FPC/Delphi are string types, which start at 1, and non-dynamic arrays (ones that are declared with a fixed size in code), which can start at almost any index you want. For instance, this is perfectly legal:
var
IntArray: array[-10..10] of Integer;
i: Integer;
begin
for i := Low(IntArray) to High(IntArray) do // loop is -10..10
//
end;
Just as an aside, any time you do anything in your loop that will reduce the number of items in your list, you should iterate backwards:
for i := List.Count - 1 downto 0 do
Otherwise, you'll iterate beyond the end of the list, because the Count is only evaluated at the time the loop starts.

Omg. That's because in cycle from 0 to Self.EventQueue.Count you iterate through Self.EventQueue.Count + 1 items.

I prefere to use
for I := 1 to Self.EventQueue.Count do
Dispose(Self.EventQueue[I-1]);
That way it is clear that nothing happens if the count is zero and the correction of the index happens at the place where it matters

Related

Change array type: 8bit type to 6bit type

I have two types and two arrays of that types in file.ads
type Ebit is mod 2**8;
type Sbit is mod 2**6;
type Data_Type is array (Positive range <>) of Ebit;
type Changed_Data_Type is array (Positive range <>) of Sbit;
and function:
function ChangeDataType (D : in Data_Type) return Changed_Data_Type
with
Pre => D'Length rem 3 = 0 and D'Last < Positive'Last / 4,
Post => ChangeDataType'Result'Length = 4 * (D'Length / 3)
Ok i can understand all of this.
For example we have arrays of:
65, 66, 65, 65, 66, 65 in 8bit values function should give to us 16, 20, 9, 1, 16, 20, 9, 1 in 6bit values.
I dont know how i can build a 6bit table from 8 bit table.
My idea of sollutions is for example taking bit by bit from type:
fill all bites in 6bit type to 0 (propably default)
if first bit (2**1) is 1 set bit (2**1) in 6bit type to 1;
and do some iterations
But i dont know how to do this, always is a problem with types. Is this good idea or i can do this with easier way? I spend last nigt to try write this but without success.
Edit:
I wrote some code, its working but i have problem with array initialization.
function ChangeDataType (D: in Data_Type) return Changed_Data_Type
is
length: Natural := (4*(D'Length / 3));
ER: Changed_Data_type(length);
Temp: Ebit;
Temp1: Ebit;
Temp2: Ebit;
Actual: Ebit;
n: Natural;
k: Natural;
begin
n := 0;
k := 0;
Temp := 2#00000000#;
Temp1 := 2#00000000#;
Temp2 := 2#00000000#;
Array_loop:
for k in D'Range loop
case n is
when 0 =>
Actual := D(k);
Temp1 := Actual / 2**2;
ER(k) := Sbit(Temp1);
Temp := Actual * ( 2**4);
n := 2;
when 2 =>
Actual := D(k);
Temp1 := Actual / 2**4;
Temp2 := Temp1 or Temp;
ER(k) := Sbit(Temp2);
Temp := Actual * ( 2**2);
n := 4;
when 4 =>
Actual := D(k);
Temp1 := Actual / 2**6;
Temp2 := Temp1 or Temp;
ER(k) := Sbit(Temp2);
n := 6;
when 6 =>
Temp1 := Actual * ( 2**2);
Temp2 := Actual / 2**2;
ER(k) := Sbit(Temp2);
n := 0;
when others =>
n := 0;
end case;
end loop Array_Loop;
return ER;
end;
IF I understand what you're asking... it's that you want to re-pack the same 8-bit data into 6-bit values such that the "leftover" bits of the first EBit become the first bits (highest or lowest?) of the second Sbit.
One way you can do this - at least for fixed size arrays, e.g. your 6 words * 8 bits, 8 words * 6 bits example, is by specifying the exact layout in memory for each array type, using packing, and representation aspects (or pragmas, before Ada-2012) which are nicely described here.
I haven't tested the following, but it may serve as a starting point.
type Ebit is mod 2**8;
type Sbit is mod 2**6;
for Ebit'Size use 8;
for Sbit'Size use 6;
type Data_Type is array (1 .. 6) of Ebit
with Alignment => 0; -- this should pack tightly
type Changed_Data_Type is array (1 .. 8) of Sbit
with Alignment => 0;
Then you can instantiate the generic Unchecked_Conversion function with the two array types, and use that function to convert from one array to the other.
with Ada.Unchecked_Conversion;
function Change_Type is new Ada.Unchecked_Conversion(Data_Type, Changed_Data_Type);
declare
Packed_Bytes : Changed_Data_Type := Change_Type(Original_Bytes);
begin ...
In terms of code generated, it's not slow, because Unchecked_Conversion doesn't do anything, except tell the compile-time type checking to look the other way.
I view Unchecked_Conversion like the "I meant to do that" look my cat gives me after falling off the windowledge. Again...
Alternatively, if you wish to avoid copying, you can declare Original_Bytes as aliased, and use a similar trick with access types and Unchecked_Access to overlay both arrays on the same memory (like a Union in C). I think this is what DarkestKhan calls "array overlays" in a comment below. See also section 3 of this rather dated page which describes the technique further. It notes the overlaid variable must not only be declared aliased but also volatile so that accesses to one view aren't optimised into registers, but reflect any changes made via the other view. Another approach to overlays is in the Ada Wikibook here.
Now this may be vulnerable to endian-ness considerations, i.e. it may work on some platforms but not others. The second reference above gives an example of a record with exact bit-alignment of its members : we can at least take the Bit_Order aspect, as in with Alignment => 0, Bit_Order => Low_Order_First; for the arrays above...
-- code stolen from "Rationale" ... see link above p.11
type RR is record
Code: Opcode;
R1: Register;
R2: Register;
end record
with Alignment => 2, Bit_Order => High_Order_First;
for RR use record
Code at 0 range 0 .. 7;
R1 at 1 range 0 .. 3;
R2 at 1 range 4 .. 7;
end record;
One thing that's not clear to me is if there's a formulaic way to specify the exact layout of each element in an array, as is done in a record here - or even if there's a potential need to. If necessary, one workaround would be to replace the arrays above with records. But I'd love to see a better answer if there is one.

Array Tally Chart

I'm trying to create a Tally Chart based on values stored in array.
I know it is possible to do this in Python, but is there a way to do this in Pascal by keeping the amount of coding to a minimum?
var numbers:array [0..9] of integer;
Sum,aNumber, count,count2:integer;
Average:real=0;
begin
randomize;
// Put 10 Random numbers into an array
for count:= 0 to 9 do
begin
aNumber:=Random(10)+1;
numbers[count]:=aNumber
end;
// Show a Tally
begin
for count:= 0 to 9 do
writeln(numbers[count] * '£');
writeln;
end;
readln;
end.
I simply want to present the outcome of the array by showing all possible values. E.g. If my array had the following random values between 1 and 10: 3,3,8,8,9 it should show:
1-
2-
3- II
4-
..
8- II
9- I
10-
Thanks.
The obvious way would be another for loop:
for count := 0 to 9 do
begin
for i := 1 to numbers[count] do
write('£');
writeln;
end
If you can settle for just one character at the right position, you could use something like:
for count := 0 to 9 do
writeln('£' : numbers[count]);
Think it works now... i created a Function to return the number of instances in each element. That result helps me to know the no. of iterations for each number.
Function TallyCount(x:integer):integer;
var i,TotalCount:integer;
begin
i:=0;
TotalCount:=0;
for i := 0 to 9 do
begin
if numbers[i] = x then
TotalCount:=TotalCount +1;
end;
result:=Totalcount;
end;

Stats with random numbers

I want to create 7 stats for a character, randomly generating a value from 3-21, with the stat's sum being no higher than 91. I've tried arranging the stats into an array, and just going through them like this:
1) add random(15) to each array member
2) computing the total, subtracting from the 91 maximum
3) dividing this difference by 7
4) do step 1 with random(difference) adding it to the stat
5) Until I hit the 91 total.
Doing this a few hundred times I seem to get a curve where the 5,6, and 7th stats tend to be higher. And sometimes I hit the 4 or 5th stat and there are no more numbers to be added, meaning then that the first few stats get the most points. I think I am approaching this the wrong way to begin with. Any ideas? I have tunnel vision at this point I think.
It sounds like you're overthinking this. I might do something like this :
const
STAT_QTY = 7;
STATSUM_MAX = 91;
STAT_MIN = 3;
STAT_MAX = 21;
type
TStatArray = Array [0..STAT_QTY-1] of integer;
Then in implementation :
function GenerateStats : TStatArray;
var statArr : TStatArray;
i, statSum, excess, debit : integer;
done : boolean;
begin
Randomize;
done := false;
while not done do begin
done := true;
statSum := 0;
for i := 0 to STAT_QTY - 1 do begin
statArr[i] := STAT_MIN + Random(STAT_MAX - STAT_MIN);
statSum := statSum + statArr[i];
end;
if statSum > STATSUM_MAX then begin
excess := statSum - STATSUM_MAX;
debit := excess div STAT_QTY + 1;
for i := 0 to STAT_QTY -1 do begin
statArr[i] := statArr[i] - debit;
end;
end;
for i := 0 to STAT_QTY -1 do begin
if statArr[i] < STAT_MIN then done := false;
end;
end;
result := statArr;
end;
This generates a list of random stats in the range 3-21. If the sum is more than 91 then divide the excess by the number of stats (use div then round up the answer) and subtract an equal number from each. In the rare case that you end up with stats less than three, just do it again. Job done.
Tested over 2000 iterations I get average stats of :
[1] : 11.13893053
[2] : 11.15692154
[3] : 11.16141929
[4] : 11.11444278
[5] : 11.10194903
[6] : 10.9800100
[7] : 10.86856572
That's a total average of 11.07 with a standard deviation of 0.11 - certainly about what one would expect from a generally random set with your construction parameters.
Here's C-ish pseudo code for a slightly different approach, assuming a suitable random(N) function that returns numbers in the range 0 - N-1.
int stats[7], deficit = 70;
for (int i = 0; i < 7; ++i)
stats[i] = 3; // initial assignments of the minimum to each stat
while (deficit)
{ int tmp = random(7); // pick a random stat to bump
if (stats[tmp] == 21) // but not if it's already at max
continue;
++stats[tmp];
--deficit;
}
Assuming your random() is uniformly distributed, that should give pretty good results.

Short VHDL for loop code i dont understand

I do understand how to convert a binary number into a decimal number but the following code thats supposed to do that doesnt make sense. I mean lets sat we have a binary number 10, then v(i) would be 0, so result stays 0. Upon the next iteration v(i) will be 1 so result will be 0 + 1 . The loop stops and the function will return the value of result which is 1 and not 2 which is the value of the binary number put into the function. Could someone tell me why I am wrong? This code comes with a university assignment so it should be correct. Thanks. :)
-------------------------------------------------------------------------------
-- convert std_logic vector v to natural
-------------------------------------------------------------------------------
FUNCTION s2n(v: std_logic_vector)
RETURN natural IS
VARIABLE result: natural := 0;
BEGIN
FOR i IN v'range LOOP
result := result * 2;
IF v(i) = '1' THEN
result := result + 1;
END IF;
END LOOP;
RETURN result;
END s2n;
The 'range loop works from left to right. The convention is for the most-significant bit to be on the left
By decoding that first, the *2 operation gets run most times on the MSB as you'd expect.
(BTW, if you want the range to go the other way for some reason, you can use the 'reverse_range attribute)

Generating permutations lazily

I'm looking for an algorithm to generate permutations of a set in such a way that I could make a lazy list of them in Clojure. i.e. I'd like to iterate over a list of permutations where each permutation is not calculated until I request it, and all of the permutations don't have to be stored in memory at once.
Alternatively I'm looking for an algorithm where given a certain set, it will return the "next" permutation of that set, in such a way that repeatedly calling the function on its own output will cycle through all permutations of the original set, in some order (what the order is doesn't matter).
Is there such an algorithm? Most of the permutation-generating algorithms I've seen tend to generate them all at once (usually recursively), which doesn't scale to very large sets. An implementation in Clojure (or another functional language) would be helpful but I can figure it out from pseudocode.
Yes, there is a "next permutation" algorithm, and it's quite simple too. The C++ standard template library (STL) even has a function called next_permutation.
The algorithm actually finds the next permutation -- the lexicographically next one. The idea is this: suppose you are given a sequence, say "32541". What is the next permutation?
If you think about it, you'll see that it is "34125". And your thoughts were probably something this: In "32541",
there is no way to keep the "32" fixed and find a later permutation in the "541" part, because that permutation is already the last one for 5,4, and 1 -- it is sorted in decreasing order.
So you'll have to change the "2" to something bigger -- in fact, to the smallest number bigger than it in the "541" part, namely 4.
Now, once you've decided that the permutation will start as "34", the rest of the numbers should be in increasing order, so the answer is "34125".
The algorithm is to implement precisely that line of reasoning:
Find the longest "tail" that is ordered in decreasing order. (The "541" part.)
Change the number just before the tail (the "2") to the smallest number bigger than it in the tail (the 4).
Sort the tail in increasing order.
You can do (1.) efficiently by starting at the end and going backwards as long as the previous element is not smaller than the current element. You can do (2.) by just swapping the "4" with the '2", so you'll have "34521". Once you do this, you can avoid using a sorting algorithm for (3.), because the tail was, and is still (think about this), sorted in decreasing order, so it only needs to be reversed.
The C++ code does precisely this (look at the source in /usr/include/c++/4.0.0/bits/stl_algo.h on your system, or see this article); it should be simple to translate it to your language: [Read "BidirectionalIterator" as "pointer", if you're unfamiliar with C++ iterators. The code returns false if there is no next permutation, i.e. we are already in decreasing order.]
template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first,
BidirectionalIterator last) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i;
for(;;) {
BidirectionalIterator ii = i--;
if (*i <*ii) {
BidirectionalIterator j = last;
while (!(*i <*--j));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
}
It might seem that it can take O(n) time per permutation, but if you think about it more carefully, you can prove that it takes O(n!) time for all permutations in total, so only O(1) -- constant time -- per permutation.
The good thing is that the algorithm works even when you have a sequence with repeated elements: with, say, "232254421", it would find the tail as "54421", swap the "2" and "4" (so "232454221"), reverse the rest, giving "232412245", which is the next permutation.
Assuming that we're talking about lexicographic order over the values being permuted, there are two general approaches that you can use:
transform one permutation of the elements to the next permutation (as ShreevatsaR posted), or
directly compute the nth permutation, while counting n from 0 upward.
For those (like me ;-) who don't speak c++ as natives, approach 1 can be implemented from the following pseudo-code, assuming zero-based indexing of an array with index zero on the "left" (substituting some other structure, such as a list, is "left as an exercise" ;-):
1. scan the array from right-to-left (indices descending from N-1 to 0)
1.1. if the current element is less than its right-hand neighbor,
call the current element the pivot,
and stop scanning
1.2. if the left end is reached without finding a pivot,
reverse the array and return
(the permutation was the lexicographically last, so its time to start over)
2. scan the array from right-to-left again,
to find the rightmost element larger than the pivot
(call that one the successor)
3. swap the pivot and the successor
4. reverse the portion of the array to the right of where the pivot was found
5. return
Here's an example starting with a current permutation of CADB:
1. scanning from the right finds A as the pivot in position 1
2. scanning again finds B as the successor in position 3
3. swapping pivot and successor gives CBDA
4. reversing everything following position 1 (i.e. positions 2..3) gives CBAD
5. CBAD is the next permutation after CADB
For the second approach (direct computation of the nth permutation), remember that there are N! permutations of N elements. Therefore, if you are permuting N elements, the first (N-1)! permutations must begin with the smallest element, the next (N-1)! permutations must begin with the second smallest, and so on. This leads to the following recursive approach (again in pseudo-code, numbering the permutations and positions from 0):
To find permutation x of array A, where A has N elements:
0. if A has one element, return it
1. set p to ( x / (N-1)! ) mod N
2. the desired permutation will be A[p] followed by
permutation ( x mod (N-1)! )
of the elements remaining in A after position p is removed
So, for example, the 13th permutation of ABCD is found as follows:
perm 13 of ABCD: {p = (13 / 3!) mod 4 = (13 / 6) mod 4 = 2; ABCD[2] = C}
C followed by perm 1 of ABD {because 13 mod 3! = 13 mod 6 = 1}
perm 1 of ABD: {p = (1 / 2!) mod 3 = (1 / 2) mod 2 = 0; ABD[0] = A}
A followed by perm 1 of BD {because 1 mod 2! = 1 mod 2 = 1}
perm 1 of BD: {p = (1 / 1!) mod 2 = (1 / 1) mod 2 = 1; BD[1] = D}
D followed by perm 0 of B {because 1 mod 1! = 1 mod 1 = 0}
B (because there's only one element)
DB
ADB
CADB
Incidentally, the "removal" of elements can be represented by a parallel array of booleans which indicates which elements are still available, so it is not necessary to create a new array on each recursive call.
So, to iterate across the permutations of ABCD, just count from 0 to 23 (4!-1) and directly compute the corresponding permutation.
You should check the Permutations article on wikipeda. Also, there is the concept of Factoradic numbers.
Anyway, the mathematical problem is quite hard.
In C# you can use an iterator, and stop the permutation algorithm using yield. The problem with this is that you cannot go back and forth, or use an index.
More examples of permutation algorithms to generate them.
Source: http://www.ddj.com/architect/201200326
Uses the Fike's Algorithm, that is the one of fastest known.
Uses the Algo to the Lexographic order.
Uses the nonlexographic, but runs faster than item 2.
1.
PROGRAM TestFikePerm;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] OF INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
WriteLn;
permcount := permcount + 1;
END;
PROCEDURE FikePerm ;
{Outputs permutations in nonlexicographic order. This is Fike.s algorithm}
{ with tuning by J.S. Rohl. The array marks[1..marksizn] is global. The }
{ procedure WriteArray is global and displays the results. This must be}
{ evoked with FikePerm(2) in the calling procedure.}
VAR
dn, dk, temp : INTEGER;
BEGIN
IF
THEN BEGIN { swap the pair }
WriteArray;
temp :=marks[marksize];
FOR dn := DOWNTO 1
DO BEGIN
marks[marksize] := marks[dn];
marks [dn] := temp;
WriteArray;
marks[dn] := marks[marksize]
END;
marks[marksize] := temp;
END {of bottom level sequence }
ELSE BEGIN
FikePerm;
temp := marks[k];
FOR dk := DOWNTO 1
DO BEGIN
marks[k] := marks[dk];
marks[dk][ := temp;
FikePerm;
marks[dk] := marks[k];
END; { of loop on dk }
marks[k] := temp;l
END { of sequence for other levels }
END; { of FikePerm procedure }
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii;
permcount := 0;
WriteLn ;
WrieLn;
FikePerm ; { It always starts with 2 }
WriteLn ;
ReadLn;
END.
2.
PROGRAM TestLexPerms;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] OF INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
permcount := permcount + 1;
WriteLn;
END;
PROCEDURE LexPerm ;
{ Outputs permutations in lexicographic order. The array marks is global }
{ and has n or fewer marks. The procedure WriteArray () is global and }
{ displays the results. }
VAR
work : INTEGER:
mp, hlen, i : INTEGER;
BEGIN
IF
THEN BEGIN { Swap the pair }
work := marks[1];
marks[1] := marks[2];
marks[2] := work;
WriteArray ;
END
ELSE BEGIN
FOR mp := DOWNTO 1
DO BEGIN
LexPerm<>;
hlen := DIV 2;
FOR i := 1 TO hlen
DO BEGIN { Another swap }
work := marks[i];
marks[i] := marks[n - i];
marks[n - i] := work
END;
work := marks[n]; { More swapping }
marks[n[ := marks[mp];
marks[mp] := work;
WriteArray;
END;
LexPerm<>
END;
END;
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii;
permcount := 1; { The starting position is permutation }
WriteLn < Starting position: >;
WriteLn
LexPerm ;
WriteLn < PermCount is , permcount>;
ReadLn;
END.
3.
PROGRAM TestAllPerms;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] of INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
WriteLn;
permcount := permcount + 1;
END;
PROCEDURE AllPerm (n : INTEGER);
{ Outputs permutations in nonlexicographic order. The array marks is }
{ global and has n or few marks. The procedure WriteArray is global and }
{ displays the results. }
VAR
work : INTEGER;
mp, swaptemp : INTEGER;
BEGIN
IF
THEN BEGIN { Swap the pair }
work := marks[1];
marks[1] := marks[2];
marks[2] := work;
WriteArray;
END
ELSE BEGIN
FOR mp := DOWNTO 1
DO BEGIN
ALLPerm<< n - 1>>;
IF >
THEN swaptemp := 1
ELSE swaptemp := mp;
work := marks[n];
marks[n] := marks[swaptemp};
marks[swaptemp} := work;
WriteArray;
AllPerm< n-1 >;
END;
END;
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii
permcount :=1;
WriteLn < Starting position; >;
WriteLn;
Allperm < marksize>;
WriteLn < Perm count is , permcount>;
ReadLn;
END.
the permutations function in clojure.contrib.lazy_seqs already claims to do just this.
It looks necromantic in 2022 but I'm sharing it anyway
Here an implementation of C++ next_permutation in Java can be found. The idea of using it in Clojure might be something like
(println (lazy-seq (iterator-seq (NextPermutationIterator. (list 'a 'b 'c)))))
disclaimer: I'm the author and maintainer of the project

Resources