Вам нужен детерминированный алгоритм
Сначала переопределите ваши требования:
- В каждом столбце должно быть хотя бы 1 число, поэтому ни один столбец не должен быть полностью пустым
- Первый столбец должен иметь числа от 1..10, второй 11..20, третий 21..30 и т. Д. До девятого столбца с 81..90
- для заполнения билета нужно всего 15 номеров
- Дополнительное требование : в каждой строке должно быть 5 чисел
Вот как бы я это сделал:
- Сначала выберите 9 рандомов (чтобы удовлетворить первое требование)
- 1..10 - одно случайное число из этого диапазона
- 11..20 - одно случайное число из этого диапазона
- ...
- 81..90 - одно случайное число из этого диапазона
- Подготовить массив (
selectNums
) чисел 1..90 и удалить все выделенные на шаге 1
- Loop
- получить случайное число из массива
selectNums
- добавьте его в свой билет и удалите из
selectNums
aray
- если выбранное число заполняет столбец из трех, то удалите все числа из этого диапазона из массива
selectNums
.
- Вернитесь к шагу 1 в цикле
Этот алгоритм будет выполнять ровно 9 шагов + 6 шагов в цикле, поэтому он является детерминированным, что лучше для использования процессора. И это также заполняет ваш билет до трех цифр в столбце и не менее 1 (если я понял ваши требования из-за слишком плохого английского в вопросе).
Yo, когда вы выбираете случайные числа, вы всегда выбираете число от 0 до selectNums
длины массива, которое даст вам позицию в массиве, откуда вы должны взять число.
Дополнительные функции для создания фактического билета
Вышеуказанные шаги приведут вас к точке, в которой вы получите ровно 15 чисел с максимум 3 числами из того же диапазона из десяти чисел. Хорошо. Все, что вам нужно сделать сейчас, это создать билет.
- определить 3 переменные:
row1Count
, row2Count
и row3Count
и установить их все в 0.
- Заполните заявку, начиная с полностью заполненных столбцов (все три числа):
- Получить первый полный столбец и заполнить его в заявке, а также увеличить все три переменные на одну.
- Удалите эти числа из массива
selectNums
.
- Вернитесь к шагу 2.1.
- Заполните заявку столбцами с двумя числами:
- Получить первые два числа столбца. Заполните их в билете, используя три возможных варианта их заполнения (1 и 2, 2 и 3, 1 и 3). Заполните первую пару, используя первую перестановку, вторую со второй и так далее. Не забудьте увеличить соответствующие переменные счетчика строк.
- удалить эти два числа из
selectNums
массива
- Вернитесь к шагу 3.1.
- Заполните заявку столбцами с одним номером (те, которые имеют только один номер):
- Получите первое число из массива
selectNums
и поместите его в строку с наименьшим количеством и вставьте в билет в этой конкретной строке. Если есть хотя бы две строки с одинаковым количеством, вы можете выбрать любую, какую пожелаете, выбрав одну из них случайным образом или выбрав первую (самую быструю).
- Удалить номер из
selectNums
массива
- Вернитесь к 4.1.
В этой части вы получите полностью заполненный тикет, в котором все столбцы содержат хотя бы одно число, а все строки содержат ровно 5 номеров.
Если меньшие числа не могут быть меньше больших, вы всегда можете добавить дополнительный шаг к этому процессу и изменить порядок номеров в тех столбцах, которые содержат более одного числа.
Одно последнее замечание
Это решение было упрощено за счет использования массивов и счетчиков. Конечно, вы можете создать полную объектную модель, которая будет функционально насыщенной и предоставит вам всю необходимую информацию. Например, у вас могут быть классы Ticket и TicketColumn:
public class TicketColumn
{
public int Count { get; }
public int? FirstRowValue { get; set; }
public int? SecondRowValue { get; set; }
public int? ThirdRowValue { get; set; }
...
public void Reorder() { ... }
}
public class Ticket
{
public TicketColumn[] Columns
public int FirstRowCount { get; private set; }
public int SecondRowCount { get; private set; }
public int ThirdRowCount { get; private set; }
...
}
Или что-то подобное. Это просто идея, что вся эта программа будет лучше в объектно-ориентированной манере.