Reputation: 29
I must create a simple Java lottery number generator modelled off of Lotto 6/49 (Ontario, Canada). The user is asked how many tickets they wish to generate. The tickets must be in ascending order of numbers and have no duplicates. For example, if I wanted 3 tickets, an output may be:
8 12 17 25 32 47
6 10 21 30 39 42
1 8 16 37 45 49
Problems arise when trying to sort the numbers. We are taught to use a bubble sort, however my duplicate check is not working properly so I will end up with an output like so:
8 18 29 29 29 29
4 12 18 18 24 24
4 12 18 24 46 46
My code is as follows:
// The "Lotto" class.
import java.awt.*;
import hsa.Console;
public class Lotto
{
static Console c; // The output console
public static void main (String[] args)
{
c = new Console ();
int t = 0;
int num[];
num = new int[10];
c.println("How many Lotto 6/49 tickets do you wish to generate?");
t = c.readInt();
c.println("****************");
for (int a = 1; a <= t; a++)
{
for (int i = 1; i <= 6; i++)
{
num[i] = (int)(Math.random() * 49 + 1);
for (int x = 1; x <= 6; x++) // duplicate check
{
for (int y = x + 1; y <= 7; y++)
{
if (num[x] == num[y])
{
num[y] = (int)(Math.random() * 49 + 1);
}
}
} // end check
for (int p = 1; p <=6; p++) // start sort
{
for (int q = 1; q <=7; q++)
{
if (num[p] < num[q])
{
int temp = num[p];
num[p] = num[q];
num[q] = temp;
}
}
} // end sort
c.print(num[i] + " ");
}
c.println();
}
} // main method
} // Lotto class
Any help into the matter or a solution would be greatly appreciated. Thanks!
Upvotes: 0
Views: 8586
Reputation: 5103
Here is my version:
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
class LotoTicket {
private static final int NUM_NUMBERS = 6;
private static final int NUM_BALLS = 99;
private static final Random random = new Random();
private final int[] numbers;
private LotoTicket(final int[] numbers) {
this.numbers = numbers;
}
public static LotoTicket generateTicket() {
final int[] numbers = new int[NUM_NUMBERS];
final List<Integer> ballPool = IntStream.range(1, 1 + NUM_BALLS)
.mapToObj(i -> i)
.collect(Collectors.toList());
for (int i = 0; i < NUM_NUMBERS; i++) {
final int draw = random.nextInt(NUM_BALLS - i);
numbers[i] = ballPool.remove(draw);
}
Arrays.sort(numbers);
return new LotoTicket(numbers);
}
public int[] getNumbers() {
return numbers;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("LotoTicket{");
sb.append("numbers=").append(Arrays.toString(numbers));
sb.append('}');
return sb.toString();
}
public static void main(final String... args) {
System.out.println(LotoTicket.generateTicket());
System.out.println(LotoTicket.generateTicket());
System.out.println(LotoTicket.generateTicket());
}
}
Here is a version that is java1.5 compliant and implements a simple bubble-sort:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
class LotoTicket {
private static final int NUM_NUMBERS = 6;
private static final int NUM_BALLS = 99;
private static final Random random = new Random();
private final int[] numbers;
private LotoTicket(final int[] numbers) {
this.numbers = numbers;
}
public static LotoTicket generateTicket() {
final int[] numbers = new int[NUM_NUMBERS];
final List<Integer> ballPool = new ArrayList<Integer>();
for (int i = 0; i < NUM_BALLS; i++) {
ballPool.add(i, i + 1);
}
for (int i = 0; i < NUM_NUMBERS; i++) {
final int draw = random.nextInt(NUM_BALLS - i);
numbers[i] = ballPool.remove(draw);
}
bubbleSort(numbers);
return new LotoTicket(numbers);
}
private static void bubbleSort(final int[] numbers) {
if (numbers.length <= 1) {
return;
}
boolean sorted;
do {
sorted = true;
for (int i = 1; i < numbers.length; i++) {
if (numbers[i - 1] > numbers[i]) {
final int temp = numbers[i];
numbers[i] = numbers[i - 1];
numbers[i - 1] = temp;
sorted = false;
}
}
} while (sorted == false);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("LotoTicket{");
sb.append("numbers=").append(Arrays.toString(numbers));
sb.append('}');
return sb.toString();
}
public static void main(final String... args) {
System.out.println(LotoTicket.generateTicket());
System.out.println(LotoTicket.generateTicket());
System.out.println(LotoTicket.generateTicket());
}
}
Upvotes: 1
Reputation: 27956
Actually neither your bubble sort nor your duplicate check is working.
For the duplicate check, you are generating a new random number if you detect a duplicate but there's nothing stopping your code generating the same duplicate. Try changing if (num[x] == num[y])
to while (num[x] == num[y])
For the bubble sort I think you've misunderstood the algorithm. The general form should be:
boolean changed = false;
do {
for (int i = 0; i < size - 1; i++) {
if (num[i] > num[i+1]) {
// swap
changed = true;
}
}
} while (changed);
While I assume it's beyond the scope of your question, the entire set can be generated in one statement with Java 8:
int[] nums = random.ints(1, 50).distinct().limit(6).sorted().toArray();
This is interpreted as: generate an infinite stream of random numbers between 1 and 49, remove duplicates, get the first 6, sort them and return them as an array.
Upvotes: 1
Reputation: 308763
This is a poor abstraction. I'd recommend embedding all the logic inside a class. Object oriented programming is about abstraction, encapsulation, and hiding details.
Here's how I'd do it:
package gambling;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
/**
* Created by Michael
* Creation date 3/21/2017.
* @link https://stackoverflow.com/questions/42932262/java-creating-simple-lottery-number-generator
*/
public class LottoTicket {
public static final int DEFAULT_NUM_TICKETS = 10;
public static final int DEFAULT_MAX_VALUE = 49;
public static final int DEFAULT_NUM_VALUES = 6;
private Random random;
public static void main(String[] args) {
int numTickets = (args.length > 0) ? Integer.parseInt(args[0]) : DEFAULT_NUM_TICKETS;
LottoTicket lottoTicket = new LottoTicket();
for (int i = 0; i < numTickets; ++i) {
System.out.println(lottoTicket.getNumbers(DEFAULT_NUM_VALUES, DEFAULT_MAX_VALUE));
}
}
public LottoTicket() {
this(null);
}
public LottoTicket(Long seed) {
this.random = (seed != null) ? new Random(seed) : new Random();
}
public Set<Integer> getNumbers(int numValues, int maxValue) {
Set<Integer> numbers = new TreeSet<>();
while (numbers.size() < numValues) {
numbers.add(this.random.nextInt(maxValue) + 1);
}
return numbers;
}
}
Upvotes: 1