Lottery number generator

So if 69 comes out 69 cannot come out again.
That's the type of algorithm.

How is this code?
I feel like this is not following the algorithm it just uses common sense and simplicity.

1
2
3
4
5
6
7
8
9
10
11
12
		for(int i = 0; i < v.size();i++)
		{
			for(int j = i+1; j < v.size(); j++)
			{
				while(v[i] == v[j])
				{
					insert = 1 + rand() % 69;
					v.erase(v.begin() + i);
					v.push_back(insert);
				}
			}
		}
Last edited on

1
2
3
insert = 1 + rand() % 69;
v.erase(v.begin() + i);
v.push_back(insert);

This is wasteful and inefficient. You generate a random number, and add it to the end, without checking if it's a duplicate? Why not check when you generate it, instead of going through that extra work?

Also, it doesn't work. It generates duplicates.

What happens if you're doing 4 such values, and your array looks like this because you've already done 3:

1 2 3

and then you generate another number, and it's 2 again. i never goes back, so you wouldn't know it was a repeat? So you can have duplicates.

Here's your code generating duplicates: http://cpp.sh/8bwzd
Hit run a few times to see it generate duplicates.


Even if it didn't generate duplicates, it doesn't scale well. If I wanted 999999999 different numbers from a choice of 1000000000, I could be waiting quite a while; I would randomly generate so many duplicates before I got a new number.

You've used rand, which is a bad choice in and of itself, for many reasons.
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful


I think you'd be better off with a vector of all the numbers, shuffling it ( http://www.cplusplus.com/reference/algorithm/shuffle/ ) , and then taking however many you want from the front. That solution would scale better.
Last edited on
How bout this code?
I have a outdated c++ compiler can someone recommend me a good c++, Java, Javascript, and HTML compiler




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
again:
		for(int i = 0; i < 5; i++)
		{
			insert = 1 + rand() % 69;
			v.push_back(insert);
		}
		
		for(int i = 0; i < v.size();i++)
		{
			finddupe = v[i];
			for(int j = i+1; j < v.size();j++)
			{
				if(finddupe == v[j])
				{
					v.clear();
					goto again;
				}
			}
		}
This is horribly inefficient. You generate the numbers, and then if you find one single duplicate, you start all over again? Picking out five numbers from 69, you'll probably get lucky and it will finish, but if you were looking for a lot of numbers, your code could literally take years to finish, starting again over and over. Literally years. This is a bad algorithm.

You need to think of a way to only pick random numbers that haven't been already picked.

And you're doing it with a goto, which is a horrible way to control program flow. You should learn the basics before you start trying to write algorithms. Learn about while loops first.
Last edited on
Here's the algorithm I'm looking for

So if one number comes out it cannot come out again.

There are 5 slots

First slot 69 choices of numbers
Second slot 68 choices
third 67 choices
fourth...
fifth...

Can I make a vector 1-69?
Choose a random index.
Delete that number
Keep doing it for 5 times.
Reload the vector back to start point
Last edited on
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
#include <iostream>
#include <vector>
#include <cstdlib>

using std::vector;
using std::cout;

int main()
{
    srand(time(NULL));
    vector<int> numbers;
    for (int i = 1; i < 70; ++i)
    {
        numbers.push_back(i);
    }

    vector<int> chosen;

    for (int i = 0; i < 5; i++)
    {
        int selectedIndex = rand() % numbers.size();
        chosen.push_back(numbers[selectedIndex]);
        numbers.erase(numbers.begin() + selectedIndex);
    }
    
    for (const auto& val : chosen)
    {
        cout << val << ' ';
    }

}

Last edited on
A couple of possibilities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <random>

int main() {
    std::mt19937 eng(std::random_device{}());
    std::uniform_int_distribution<int> dist(0, 68);

    std::vector<bool> picked(69, false);
    for (int i = 0; i < 5; i++) {
        int r;
        do
            r = dist(eng);
        while (picked[r]);
        picked[r] = true;
    }

    for (int i = 0; i < 69; i++)
        if (picked[i])
            std::cout << i + 1<< ' ';
    std::cout << '\n';
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <random>
#include <numeric> // iota
#include <algorithm>

int main() {
    std::mt19937 eng(std::random_device{}());
    std::vector<int> v(69);
    std::iota(v.begin(), v.end(), 1);

    std::shuffle(v.begin(), v.end(), eng);
    // for (int n: v) std::cout << n << ' '; std::cout << '\n';

    std::vector<int> ticket;
    for (int i = 0; i < 5; i++)
        ticket.push_back(v[i]);

    std::sort(ticket.begin(), ticket.end());
    for (int n: ticket) std::cout << n << ' '; std::cout << '\n';
}

Last edited on
Here is a simple way to get 10 non repeating numbers.

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
#include <iostream>
#include <vector>
#include <ctime>

using namespace std;

int main() {
	srand(time(0));

	vector<int> v(10, 0);

	int a;
	for (int i = 0; i < v.size(); i++ ) {
		a = rand() % 69;
		for (int j = 0; j < v.size(); j++) {
			if (a == v[j]) {
				a = rand() % 69;
				j = 0;
			}
		}
		v[i] = a;
	}

	for (int &bob : v) {
		cout << bob << endl;
	}

	cin.get();
	return 0;
}
Last edited on
That algorithm can produce duplicates. Here is it, fetching 40 numbers from a range of 50 ;http://cpp.sh/9purvk

Press run a few times, see the repeats.
Last edited on
Well now that sucks. But why any repeats? I produce a random number, then compare it to all the others. If it matches then it should draw a new random number and compare all over again.
I suppose there is another way to make a repeat impossible. You have 2 vectors. Vector a has one of every possibility. Randomly choose a number from vector a and add it to vector b. But then delete that number from vector a so it can't be selected again.

Edit:
opps, this idea was mentioned already.
Last edited on
Yes. That's what one of the posts above does.
most of this sounds like too much work.
make a vector of bools, all false. pick a number in range. If the vector[value] is true, pick a new number. If it is false, set it to true and use the number. Repeat until happy. (This won't work if you are picking most of the numbers , eg pick 80 not repeats from 0-100, this is horrible. But you are not doing that, you are picking just a few, right? pick 5 or so from 70 possible, odds of repeats are low enough that this simple algorithm works and works fast).


Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
		for(int i = 1;i < 70; i++)
		{
			base.push_back(i);
		}
		
		for(int i = 0;i < 5;i++)
		{
			pickindex = rand() % endbound;
			v.push_back(base[pickindex]);
			base.erase(base.begin()+pickindex);
			endbound--;
		}


This is what I came up with.

Steps
------------
Choose a random index.
Delete that number
Keep doing it for 5 times.
Reload the vector back to start point
Last edited on
-------------------NEXT STEP IS----------------------
I should be a professor lol

I need to have a combination of lottery numbers
with 1 or 2 pairs from each sets

What are sets?
Set 1: 1-10
Set 2: 11-22 If you take a look at the powerball ticket, each set is each line on
Set 3: 23-34 the ticket.
Set 4: 35-46
Set 5: 47-58
Set 6: 59-69

The user can choose how many pairs they want and but the program will choose the set randomly to pick from.

If user chooses 0 pair
Example output would be
1 11 23 35 47

If user chooses 1 pair
Example output would be
1 11 15 26 47

If user chooses 2 pairs
Example output would be
1 9 12 14 58

1 5 60 64 68 is not allowed because they are triplets not pairs.
Last edited on
i will send you the whole code for the powerball program so just use this program to generate your random number

DO NOT PLAY QUICK PICKS! DO NOT PLAY SCRATCH OFFS

I BOUGHT BOOKS AND BOOKS OF SCRATCHS OFFS LOOK FOR A JACKPOT WINNER I ONLY GOT 50% OF MY MONEY BACK
Lottery. You have N balls. Each has a unique symbol. You put them all into a large bowl.

Do you now proceed by picking one ball from bowl, record its symbol and then put the ball back to the bowl? Do the real life lotteries put the already picked balls back to the bowl? Do they keep picking and putting back more until enough unique symbols have been seen?

No. The already picked balls stay out of the bowl and therefore same symbol cannot possibly show up more than once.

tpb did already post this logical solution:
1
2
3
4
5
6
std::vector<int> bowl( N );
std::iota( bowl.begin(), bowl.end(), 1 );
// bowl now has symbols [1..N]

std::shuffle( bowl.begin(), bowl.end(), eng );
// First K (where K<=N) values in the bowl are now both random and unique 
Last edited on
I found it!! Why my code made duplicates!!! And fixed that som bitch!!!

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
#include <iostream>
#include <vector>
#include <ctime>

using namespace std;

int main() {
	srand(time(0));

	vector<int> v(10, 0);

	int a;
	for (int i = 0; i < v.size(); i++ ) {
		a = rand() % 69;
		for (int j = 0; j < v.size(); j++) {
			if (a == v[j]) {
				a = rand() % 69;
				j = -1; // This should not be a zero!!!!
			}
		}
		v[i] = a;
	}

	for (int &bob : v) {
		cout << bob << endl;
	}

	cin.get();
	return 0;
}
Topic archived. No new replies allowed.