I would like to make a program in pascal that chooses 6 random integers between 1 and 49. each number should be unique i.e. you cannot have '8,22'22'32'37'43' because the '22' is repeated.How could I Implement this is in Delphi.
I can get 6 random numbers between 1 - 49 by using the following code.
for i := 1 to 6 do
begin
num[i] := random(49) + 1
end
{next};
I would do it like this:
It's probably not the most efficient way, but it's easy to implement, easy to understand, and, most crucially, easy to reason about the distributional properties of your sampling method.
For the shuffle, use Fisher-Yates shuffle. I implement that like this, in a generic method:
procedure TRandomNumberGenerator.Permute<T>(var Values: array of T);
var
i, Count: Integer;
begin
Count := Length(Values);
for i := 0 to Count-2 do
TGeneric.Swap<T>(Values[i], Values[i + Uniform(Count-i)]);
end;
where Uniform(N)
is the function of my RNG that returns a value drawn from the uniform distribution over 0..N-1
. You could replace that with Random
in your code. And TGeneric.Swap<T>
swaps the two elements.
You could modify this to work on an array of integers like so:
procedure Swap(var lhs, rhs: Integer);
var
tmp: Integer;
begin
tmp := lhs;
lhs := rhs;
rhs := tmp;
end;
procedure Permute(var Values: array of Integer);
var
i, Count: Integer;
begin
Count := Length(Values);
for i := 0 to Count-2 do
Swap(Values[i], Values[i + Random(Count-i)]);
end;
Of course, you only need to perform the first six iterations of the loop, so a very efficient version would be like this:
function Choose(M, N: Integer): TArray<Integer>;
var
i: Integer;
Values: TArray<Integer>;
begin
Assert(M>0);
Assert(N>=M);
SetLength(Values, N);
for i := 0 to N-1 do
Values[i] := i+1;
for i := 0 to Min(M-1, N-2) do
Swap(Values[i], Values[i + Random(N-i)]);
Result := Copy(Values, 0, M);
end;
You would call this passing 6 and 49:
Values := Choose(6, 49);
If you were a mad performance freak then I think it would be hard to beat this:
type
TArr6 = array [0..5] of Integer;
PArr6 = ^TArr6;
TArr49 = array [0..48] of Integer;
const
OrderedArr49: TArr49 = (
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
);
function Choose6: TArr6;
var
i: Integer;
Values: TArr49;
begin
Values := OrderedArr49;
for i := 0 to high(Result) do begin
Swap(Values[i], Values[i + Random(Length(Values)-i)]);
end;
Result := PArr6(@Values)^;
end;
I should say that I doubt that performance would be the driving factor here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With