-1

How can I fill 2 dimensional array with unique random numbers (different numbers in a row/colum)?

I have already done it for 1 dimensional array:

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random();

        int[] x = new int[10];

        for(int i = 0; i < x.Length; i++)
        {
            x[i] = r.Next(9);

            for(int j = 0; j < i; j++)
            {
                if(x[i] == x[j])
                {
                    i--;
                    break;
                }
            }
        }

        for(int i = 0; i < x.Length; i++)
        {
            Console.WriteLine(x[i]);
        }

        Console.ReadKey();
    }
}
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Irakli
  • 1
  • 1

3 Answers3

3

Since you don't want any duplicates, using Random repeatedly until you have one of each is not the best approach. Theoretically, an algorithm like that could run for a very long time, if the randomizer does not provide the desired values early on.

Since you know what values you want, but want them in a random order, a shuffle algorithm is usually a better approach. A shuffle algorithm would allow you to generate an array of the desired values and then shuffle them to get them in random order.

The easiest way to get it working for multidimensional arrays, would probably be to have all the desired values in a one-dimensional array first, shuffle it and then convert the array into a multidimensional array. However, it is possible to generalize a shuffling algorithm to work on multidimensional arrays.

An example of how the code would look like is provided in the referenced answers.

Community
  • 1
  • 1
MAV
  • 7,260
  • 4
  • 30
  • 47
0

This sounds a little like homework. Here's the idea of shuffling a fixed range (in your case, 10x10) of integers into a two-dimensional integer array such as int[10,10]:

using System;
using System.Linq;
using System.Collections;

class MainClass {

  public static void Main (string[] args) {
    // table dimension (assumes a square)
    var dim = 10;
    var table = new int?[dim, dim];

    // 100 integers: 0..99
    var queue = new Queue(Enumerable.Range(0, dim * dim).ToList<int>());
    var rng = new Random();


    int x = dim / 2, y = dim / 2;

    // Acceptable shuffle? As long as the queue has anything in it, try to place the next number
    while(queue.Count > 0) {
        x = rng.Next(dim);  // still using random, not great! :(
        y = rng.Next(dim);

        if(table[x,y] == null)
            table[x,y] = (int)queue.Dequeue();
    }

    // print output so I know I'm not crazy
    for(var i = 0; i < dim; i++) {
        Console.Write("Row {0}: [", i);
        for(var j = 0; j < dim; j++) {
            Console.Write("{0,4}", table[i,j]);
        }
        Console.WriteLine("]");
    }
  }
}

Outputs:

Mono C# compiler version 4.0.4.0

Row 0: [  55  45  38  23  88  46   7  89   0  94]
Row 1: [   2  92  43  51  58  67  82  90  79  17]
Row 2: [  29  64  16   8  50  14   1  25  26  73]
Row 3: [  97  37  13  20   4  75  98  80  48  12]
Row 4: [  33  27  42  74  95  35  57  53  96  60]
Row 5: [  59  86  76  40   6  11  77  49  93  61]
Row 6: [   5  72   9  91  68  30  39  69  99  21]
Row 7: [  52  31  28  34   3  81  18  62  10  71]
Row 8: [  66  24  44  54  56  85  84  22  47  63]
Row 9: [  65  36  83  41  15  19  87  78  70  32]
clarkitect
  • 1,720
  • 14
  • 23
0

Here's my shot at implementing MAV's answer:

private Random random = new Random();

private void Shuffle(ref int[] array)
{
    int r, temp;
    for (int i = array.Length - 1; i >= 0; i--)
    {
        r = random.Next(i + 1);
        temp = array[r];
        array[r] = array[i];
        array[i] = temp;
    }
}

public int[,] GetUniqueArray()
{
    int[,] array = new int[10,10];

    int[] temp = Enumerable.Range(0, 100).ToArray();
    Shuffle(ref temp);

    for (int i = 0; i < temp.Length; i++)
    {
        array[i / array.GetLength(0), i % array.GetLength(1)] = temp[i];
    }

    return array;
}

Like he says, brute-forcing the array's contents to be random as well as unique can cause problems depending on how big the array is. If you run into a situation where you are generating a lot of collisions, then it can cause your program to slow to a crawl while it generates hundreds of random numbers for a single array index just blindly looking for one that hasn't been used yet.

This method is better, as you start out with an array of the desired size that is already populated with unique numbers, and from that point you merely randomize their order. You get the desired outcome with a constant runtime and far fewer issues.

Abion47
  • 22,211
  • 4
  • 65
  • 88