1

i have this code:

Random num = new Random();
            int check = CheckIfOdd(num.Next(1, 1000000));
            int counter = 1;

            while (check <= 0)
            {
                if (check % 2 == 0)
                {
                    check = CheckIfOdd(num.Next(1, 1000000)); ;
                }
                counter++;
            }
            int[] nArray = new int[check];
            int arLength = 0;
            //generate arrays with pairs of numbers, and one number which does not pair.
            for (int i = 0; i < check; i++)
            {
                arLength = nArray.Length;

                if (arLength == i + 1) 
                {
                    nArray[i] = i + 1;
                }
                else
                {
                    nArray[i] = i;
                    nArray[i + 1] = i;
                }
                i++;
            }

which does kinda work, but not as well as i would like.

It should generate an array with between 1 - 1 million elements, and the numbers within can be between 1 - 1 billion.

it has to make two pairs of each number, in random locations in the array ( which it doesn't now ) and then it should contain 1 number which has no pair...

I am just looking for a better way of doing it, since it isn't in random locations, and it doesn't generate numbers correctly between 1- 1 billion.

Edit I have been suggested this: (by oerkelens)

var total = new Random().Next(500000) * 2 + 1;
            var nArray = new int[total];
            for (var i = 1; i < total; i += 2)
            {
                nArray[i] = i;
                nArray[i - 1] = i;
            }
            nArray[total - 1] = total;

Which is better, and not as much code, but it doesn't place the values in random order.

Edit 2 This almost does what i need, but it does not generate the right amount. as stated, it should generate up to x elements, with numbers between 1-y

Random r = new Random();
int[] output = Enumerable.Range(0, 11).Select(x => x / 2).OrderBy(x => r.Next()).ToArray();

by Enigmativity

andrelange91
  • 1,018
  • 3
  • 21
  • 48
  • 2
    so you are writing unit test for this one ;) ? https://stackoverflow.com/questions/45855564/find-number-with-no-pair-in-array – M.kazem Akhgary Aug 24 '17 at 08:16
  • yes, kinda, but i want to optimize my code – andrelange91 Aug 24 '17 at 08:17
  • `arLength = nArray.Length` this will always be exactly equal to `check`, because that is the array length that you have defined. The length of an array does not account for how many things you've **added** to it, it only account for the length that you requested it to be. – Flater Aug 24 '17 at 08:17
  • 1
    Use this to generate a sorted collection, and then randomize it after. It's often easier to break a task like this down into smaller bits, rather than trying to do it all at once. Here's an answer to another question that deals with randomizing collections: https://stackoverflow.com/a/1262619/2144491 – Mikal Schacht Jensen Aug 24 '17 at 08:41

1 Answers1

4

Try this code:

int[] output = Enumerable.Range(0, 11).Select(x => x / 2).ToArray();

It produces an array with these values:

{ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5 }

You should be able to extend this to as many elements you need.

If you want the output in a random order then try this:

Random r = new Random();
int[] output = Enumerable.Range(0, 11).Select(x => x / 2).OrderBy(x => r.Next()).ToArray();

In one run, as an example, I got this:

{ 0, 4, 1, 2, 2, 4, 5, 3, 3, 1, 0 }

To produce a large number of random pairs with one single element you can do this:

Random r = new Random();
int pairs = 5; //elements = 2 * pairs + 1;
int max = 100;
int[] output =
    Enumerable
        .Range(0, pairs)
        .Select(x => r.Next(1, max + 1))
        .SelectMany(x => new [] { x, x })
        .StartWith(r.Next(1, max + 1))
        .OrderBy(x => r.Next())
        .ToArray();

However, this doesn't guarantee that you don't end up with collisions of 3, 4, or more, number clashes.


This doesn't require "System.Interactive":

int[] output =
    new [] { r.Next(1, max + 1) }
        .Concat(
            Enumerable
                .Range(0, pairs)
                .Select(x => r.Next(1, max + 1))
                .SelectMany(x => new [] { x, x }))
        .OrderBy(x => r.Next())
        .ToArray();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • if i wanted between 1-1 million elements, with numbers between 1 - 1 billion. how do i achive this ? so far as i can read if i set the range to 0-1 billion, it would generate numbers between that, but up to 500 million elements. is this correct ? – andrelange91 Aug 24 '17 at 08:45
  • @andrelange91 - You might need to explain more clearly what you need. Based on the algorithm in your question it appeared that my code would either be suitable or you could adapt it fairly trivially to suit. However, I don't understand how you can have numbers paired off like you ask and starting with `0` (`for (int i = 0; i < check; i++)`) like you had in your code and have up to 1 million elements with numbers up to 1 billion. It just doesn't make sense. Can you please explain more clearly? – Enigmativity Aug 24 '17 at 09:13
  • i am sorry i am not clear enough, i need a random amount of elements, ie {0, 1, 2, 3, 4 } <- random amount of elements, and the numbers within, should also be random, between 1- 1 billion. You got it right with it, making pairs and one which has no pair. – andrelange91 Aug 24 '17 at 09:15
  • @andrelange91 - I've added an answer that does pretty much what you want. – Enigmativity Aug 24 '17 at 10:14
  • collisions, would mean there ends up with more single numbers ? – andrelange91 Aug 24 '17 at 10:16
  • i get an error on startwith, does not contain a definition or extension. – andrelange91 Aug 24 '17 at 10:18
  • @andrelange91 - Sorry, that's because I have the "System.Interactive" library installed. You can NuGet that. Otherwise I'll add a variant that doesn't need it. – Enigmativity Aug 24 '17 at 10:24
  • cool, this works, though i get a outofmemory exception, when using 1 million as max and 500 million as pairs, ^^ i quess it is too many numbers to handle it. – andrelange91 Aug 24 '17 at 10:30
  • i am giving the answered as this is as close as i think i am going to get. – andrelange91 Aug 24 '17 at 10:33