Goodnight. Guys, please hurt not to kick and help again :)

There is such a task

To test the residual knowledge of students after the summer holidays, the primary school teacher decided to start each lesson by setting an example from the multiplication table for each student, but there are 15 people in the class, and the examples among them should not be repeated. To help the teacher, write a program that will display 15 random examples from the multiplication table (from 2x2 to 9x9, because the multiplication tasks by 1 and by 10 are too simple). Moreover, among the 15 examples there should not be recurring (examples 2x3 and 3x2 and similar pairs should be considered repetitive).

Just output as 15 different examples no problems. Through the creation of an array of 15 rows and 3 columns.

public class Main { public static void main(String[] args) { int[][] massiv = new int[15][3]; for (int x = 0; x < massiv.length; x++) { massiv[x][0] = (int) (Math.random() * 9 + 1); massiv[x][1] = (int) (Math.random() * 9 + 1); massiv[x][2] = (massiv[x][0]) * (massiv[x][1]); } for (int x = 0; x < massiv.length; x++) { System.out.println("Пример №" + (x + 1) + ":\t\t" + massiv[x][0] + " * " + massiv[x][1] + " = " + massiv[x][2]); }} } 

and I don’t have any thoughts on how to make a check, tell me, at least in what direction to dig?

  • And you can add a variant with a lot. Only the numbers in each generated pair must be immediately ordered. - avp

2 answers 2

See it. For starters, what examples do we have? Here are some:

 2 x 2 2 x 3 2 x 4 ... 2 x 9 3 x 3 3 x 4 ... 3 x 9 4 x 4 ... 4 x 9 ... 9 x 9 

There are only 8 + 7 + ... + 1 = (the sum of an arithmetic progression) = (8 + 1) * 8/2 = 36. For the time being, we encode them simply with numbers from 0 to 35. Our first subtask is to select a sample from the set of numbers 15 pieces. This is done by sampling with a tank (Whip, Programming Art, 3.4.2S):

 const int N = 36; const int n = 15; int[] values = new int[n]; Random random = new Random(); int targetIdx = 0, source = 0; while (targetIdx < n) { int r = random.nextInt(N - source); if (r < n - targetIdx) values[targetIdx++] = source; source++; } 

So, we have an array of random non-repeating numbers of examples. It remains to issue an example by the number of the example.

To do this, first find the column. Let the column number be k , then k is the largest integer such that

 (1 + k) * k / 2 <= v 

i.e

 k * k + k <= 2 * v k * k + k + 1/4 <= 2 * v + 1/4 (k + 1/2)^2 <= 2 * v + 1/4 k + 1/2 <= sqrt(2 * v + 1/4) k = floor(sqrt(2 * v + 1/4) - 1/2) 

The string is now easy.


PS: Instead of calculating the root, you can apply nano-optimization and use the pre-calculated array. Will give a benefit in a fraction of a millisecond.

  • one
    And the second factor will always be not less than the first? Not good ... - alexlz
  • @alexlz: Yes, you can mix another random.nextBool . - VladD pm

Try using the following code:

 int[][] mass = new int[15][3]; for (int x = 0; x < mass.length; x++) { label: while (true) { int a = (int) (Math.random() * 9 + 1); int b = (int) (Math.random() * 9 + 1); for (int y = 0; y < mass.length; y++) { if ((a == mass[y][0] && b == mass[y][1]) || (b == mass[y][0] && a == mass[y][1])) { continue label; } } mass[x][0] = a; mass[x][1] = b; mass[x][2] = (mass[x][0]) * (mass[x][1]); break label; } } for (int x = 0; x < mass.length; x++) { System.out.println("Пример №" + (x + 1) + ": " + mass[x][0] + " * " + mass[x][1] + " = " + mass[x][2]); } 
  • one
    Add a description of what is happening in your code - Grundy