Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The key is to not check if you have generated the number before, which gets very expensive when looking for only 1 remaining number, but to generate the numbers 1-100 in order, and then shuffle.</p> <p>In your code, when you have generated 99 out of the 100 numbers, you will loop around, generating random numbers, until you find that 1 remaining number. That's why the average case in your version is so bad.</p> <p>If instead you just shuffle an array, you only need to have as many random numbers as you have shuffle operations, and only as many shuffle operations as you need numbers output. </p> <p>(For full details on shuffling, look up the <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle" rel="nofollow noreferrer">Fisher-Yates</a> shuffle, specifically the inside-out variant which can generate a shuffled array in place)</p> <p>To generate the random numbers, you need a variable generator, rather than a fixed 1-50 one. You can approach this in a variety of ways, but be very careful of introducing skew into the results, if you really want the output to have a good distribution across the possible states.</p> <p>For example, I would recommend using an integral number of bits, with shifting, rather than attempting to use a modulo. This does involve a certain amount of looping if the values are outside of the desired range, but without being able to modify the original random number generation, your hands are somewhat tied.</p> <pre><code>static int bits = 0; static int r100 = 0; static int randomInt(int range) { int ret; int bitsneeded = 32 - Integer.numberOfLeadingZeros(range - 1); do { while(bits &lt; bitsneeded) { int r = (getrnd50()-1) * 50 + getrnd50()-1; if(r &lt; 2048) { r100 &lt;&lt;= 11; r100 |= r; bits += 11; } } ret = r100 &amp; ((1 &lt;&lt; bitsneeded) - 1); bits -= bitsneeded; r100 &gt;&gt;= bitsneeded; } while(ret &gt;= range); return ret + 1; } </code></pre> <p>This implementation will use something in the region of 150 random numbers for your 100 value shuffled array. This is worse than the modulo version, but better than 2x the input range, which was the best case of the original version. There is, if the random generation was truly random, still a worst-case scenario of infinity, but random generation doesn't typically work like that. If it did, I'm not sure unskewed results are realistic given the constraints.</p> <p>For illustration, as the results are subtle, here's a graph of my suggested random routine, versus a modulo version:</p> <p><img src="https://i.stack.imgur.com/ExtFs.png" alt="Graph of random generators"></p> <p>So in summary, I think that while your random generation is a bit inefficient, and could be improved, the really big win that interviewer was looking for, is in not needing so many random numbers in the first place, by doing a shuffle rather than repeated searching with an ever decreasing probability.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload