Create a numerical probability generator - Euromillions Generator - delphi-7

I'm asking for help. I'm looking to create a numerical probabilities generator but let me explain exactly the kind of help I´m asking to.
I've already came up with a source code that will randomly generate numbers, but I want to make some numbers with more chance to be generated than others.
So far I've got this, but this will only generate this numbers and here´s where my brain explodes. This code won´t distinguish the numbers, it doesn't generate a 12.. It generates either a 1 or 2.
I want to make it to "see" lets say.. a 1 a 2 and a 12
Please, help me on this one.
var
i: integer;
const
str = '0102030405060708091011121314151617181920212223242 526272829303132333435363738394041424344454647484950';
max = 5;
begin
Edit1.Text := '';
Randomize;
for i := 1 to max do
Edit1.Text := Edit1.Text + str[random(length(str))+1];
Sincerly,
Hopsins

To pull a number from str, you need two digits. To select '01', you would pull out the two characters starting at position #1. For '02', you need to start at position #3. '03' starts at position #5. You might want to use the expression:
copy ( str, random ( length(str) div 2 ) * 2 + 1, 2 )
Here, length(str) is 100, length(str) div 2 is 50.
random generates a number from 0 through 49.
Multiply that by 2, and add 1, to get the index of the first character.
Then use copy to pull out two characters starting at that position.

Related

Binary random number with a specific number of ones

I am looking to randomly insert ones into a binary number where each specific set of bits has a fixed number of ones.
For example, if I have a 15 bit number, all 3 sets of 5 bits must have exactly 3 ones each. I need to generate say, 40 such unique binary numbers.
import numpy as np
N = 15
K = 9 # K zeros, N-K ones
arr = np.array([0] * K + [1] * (N-K))
np.random.shuffle(arr)
This is something that I discovered, but the issue is, here, this solution means that it is not necessary that the ones are distributed in the way that I want - through this solution, all ones can be grouped together right at the beginning, such that the last set of 5 bits are all zeroes - and this is not what I'm looking for.
Also, this method does not guarantee that all combinations I have are unique.
Looking for any suggestions regarding this. Thank you!
If I understand the question correctly, you could do something like this in Python:
import random
def valgen():
set_bits = [
*random.sample(range(0, 5), 3),
*random.sample(range(5, 10), 3),
*random.sample(range(10, 15), 3),
]
return sum(1<<i for i in set_bits)
i.e. sample three sets of integer values, without replacement, in each block and set those bits in the result.
if you want 40 unique values, I'd do:
vals = {valgen() for _ in range(40)}
while len(vals) < 40:
vals.add(valgen())
see the birthday problem for why you should expect approx one duplicate per set of 40

I'm having some problems with even and odd numbers in Pascal

I'm having some problems with my program in Pascal. I need to create a program which will calculate even and odd sums of a number's decomposition. For example, if my number is 10 the program should write that sum of even numbers is 30 (since 2,4,6,8,10 are the even numbers) and it should write that sum of odd numbers is 25 (since 1,3,5,7,9 are odd numbers). Here is what i tried
program odd_even;
var
a,sumeven,sumodd,even,odd : integer;
begin
writeln('Enter a number : ');
readln(a);
if a mod 2 = 0 then a=even;
if a mod 2 not=0 then a=odd;
for a:1 to a do begin
sumeven:=0;
sumeven:=sumeven+even
writeln('Sum of even numbers is : ',sumeven);
sumodd:=0;
sumodd:=sumodd+odd;
writeln('Sum of odd numbers is : ',sumodd),
end;
readln
end.
The compiler says that my if part is illegal but I don't understand how I can fix it, I also tried with else but it says the same thing. If someone could help me out I would be really thankful.
First of all, welcome to the world of programming!
There are several errors in your code:
The initialization of your result variables
sumEven:=0;
sumOdd:=0;
should be before your for loop
checking odd/even
if a mod 2 = 0 then a=even;
if a mod 2 not=0 then a=odd;
should be inside your loop and you should check not whether a (your input number) is odd/even but the value of your loop variable:
for i := 1 to a do
begin
if (i mod 2 <> 0) then sumOdd := sumOdd+1 else sumEven := sumEven+1 ;
end;
Printing the results should be of course after your loop.
Good luck!

How to insert the probability of randomizing a specific number in pascal

I've been trying lately to write a program(a text based game) but I only know some commands and don't understand every command very well.
What I am trying to do is a hit chance. Lets say that I want the program to have
90% chance of choosing number 1 (which means hit) and
10% to choose number 0 (which means miss).
I saw the same question Here but I don't understand the commands because I've never used them (I'm talking about set.seed and sample). Could someone explain to me how do they work? Is there another way (easier to understand? I don't mind if it consumes more resource)
program Project1;
{$ASSERTIONS ON}
function getProb(aProbability: Integer): boolean;
begin
result := aProbability > (100 - random(100));
end;
procedure miss;
begin
writeln('miss');
end;
procedure hit;
begin
writeln('hit');
end;
var
i, success, probability, errorMarge: Integer;
const
combat: array[boolean] of procedure = (#miss, #hit);
begin
// show that getProb() is reliable
errorMarge := 4;
success := 0;
probability := 80;
for i in [0..99] do
Inc(success, Byte(getProb(probability)));
assert(success >= probability - errorMarge);
success := 0;
probability := 50;
for i in [0..99] do
Inc(success, Byte(getProb(probability)));
assert(success >= probability - errorMarge);
// example usage
combat[getProb(20)];
combat[getProb(80)];
combat[getProb(90)];
readln;
end.
Not knowing what "commands" you know, this is hard to answer w/o generalizing.
If you only need to choose between two values, then generate a random value in whatever range you know how to, and compute the dividing line based on your probability. So, for your example, if you can generate a value between 0 and 1, if it is <= 0.9, hit.
This can be extended to multiple values by adding the successive probabilities. So if you have 4 values to choose between, each with 25% probability, get you random value between 0 and 1: if it is less than 0.25, choose 0 else if less than 0.5, choose 1 else if less than 0.75 choose 2 otherwise choose 3.

Efficient database lookup based on input where not all digits are sigificant

I would like to do a database lookup based on a 10 digit numeric value where only the first n digits are significant. Assume that there is no way in advance to determine n by looking at the value.
For example, I receive the value 5432154321. The corresponding entry (if it exists) might have key 54 or 543215 or any value based on n being somewhere between 1 and 10 inclusive.
Is there any efficient approach to matching on such a string short of simply trying all 10 possibilities?
Some background
The value is from a barcode scan. The barcodes are EAN13 restricted circulation numbers so they have the following structure:
02[1234567890]C
where C is a check sum. The 10 digits in between the 02 and the check sum consist of an item identifier followed by an item measure. There might be a check digit after the item identifier.
Since I can't depend on the data to adhere to any single standard, I would like to be able to define on an ad-hoc basis, how particular barcodes are structured which means that the portion of the 10 digit number that I extract, can be any length between 1 and 10.
Just a few ideas here:
1)
Maybe store these numbers in reversed form in your DB.
If you have N = 54321 you store it as N = 12345 in the DB.
Say N is the name of the column you stored it in.
When you read K = 5432154321, reverse this one too,
you get K1 = 1234512345, now check the DB column N
(whose value is let's say P), if K1 % 10^s == P,
where s=floor(Math.log(P) + 1).
Note: floor(Math.log(P) + 1) is a formula for
the count of digits of the number P > 0.
The value floor(Math.log(P) + 1) you may also
store in the DB as precomputed one, so that
you don't need to compute it each time.
2) As this 1) is kind of sick (but maybe best of the 3 ideas here),
maybe you just store them in a string column and check it with
'like operator'. But this is trivial, you probably considered it
already.
3) Or ... you store the numbers reversed, but you also
store all their residues mod 10^k for k=1...10.
col1, col2,..., col10
Then you can compare numbers almost directly,
the check will be something like
N % 10 == col1
or
N % 100 == col2
or
...
(N % 10^10) == col10.
Still not very elegant though (and not quite sure
if applicable to your case).
I decided to check my idea 1).
So here is an example
(I did it in SQL Server).
insert into numbers
(number, cnt_dig)
values
(1234, 1 + floor(log10(1234)))
insert into numbers
(number, cnt_dig)
values
(51234, 1 + floor(log10(51234)))
insert into numbers
(number, cnt_dig)
values
(7812334, 1 + floor(log10(7812334)))
select * From numbers
/*
Now we have this in our table:
id number cnt_dig
4 1234 4
5 51234 5
6 7812334 7
*/
-- Note that the actual numbers stored here
-- are the reversed ones: 4321, 43215, 4332187.
-- So far so good.
-- Now we read say K = 433218799 on the input
-- We reverse it and we get K1 = 997812334
declare #K1 bigint
set #K1 = 997812334
select * From numbers
where
#K1 % power(10, cnt_dig) = number
-- So from the last 3 queries,
-- we get this row:
-- id number cnt_dig
-- 6 7812334 7
--
-- meaning we have a match
-- i.e. the actual number 433218799
-- was matched successfully with the
-- actual number (from the DB) 4332187.
So this idea 1) doesn't seem that bad after all.

How to get a random number in pascal?

I want to get a random number in pascal from between a range. Basically something like this:
r = random(100,200);
The above code would then have a random number between 100 and 200.
Any ideas?
The built in pascal function only lets you get a number from between 0-your range, while i need to specify the minimum number to return
Just get a random number with the correct range (ie 100 to 200 would be range 100) then add the starting value to it
So: random(100) + 100 for your example
As already pointed out, you should use
myrandomnumber := random(span) + basenumber;
However, to get better quality random numbers, you should call
randomize();
once, on start of your application, to initialize the random number generator.
Couldn't you just declare a starting variable and an end variable and pass random those? e.g.
var
varMyRandomNumber, x, y := extended;
begin
x := 100;
y := 200;
varMyRandomNumber := random(x,y);
ShowMessage(IntToStr(varMyRandomNumber));
end;
?
There's a good example here of using a for loop to set starting and end values : http://www.freepascal.org/docs-html/rtl/system/random.html
Use RandomRange or RandomFrom:
function RandomRange(const aFrom: Integer; const aTo: Integer): Integer;
RandomFrom returns a random element from the array AValues. The return value has the same type as the type of the array elements.
first of all, i recommend you to use Randomize at the beginning of the program (it changes the algorithm of selecting the number).
To get a random number between some two numbers you need this:
Result:=Min+random(10000)mod max + 1;
I don't remember the maximum value for random, so you can change it (it don't changes anything).
By using 'mod' you get module from division Random and max. +1 is needed, because you never get the number that = max, only the number that =max-1, so you need to write +1.
Good luck!
You can make it like
Int:=Random(100);
it give's 100 random numbers.
then when you display it or use it just add 101 to that integer so its between 100 and 200

Resources