简体   繁体   中英

Reduce W to be between X and Y

I will take an answer in any language... even pseudo-code... even just an idea or a concept on how to do this. (I'm working with VB.NET myself.)

I'll give you 3 values:

  • W = 20141231
  • X = 100
  • Y = 200
  • Z = ?

You have to mathematically reduce W... so that it will fall into the range between X and Y (inclusively). I'll call your result Z.

If you run that code over and over again... W will always be reduced to the same value Z.

If I give you a new value tomorrow for W... it will also be reduced, but to a different value for Z. (I made W based on the current date, just to keep things simple, and generate a different value for Z each day.)

Nothing can be random.

And no one will be able to predict what Z will be just by looking at W. (Without stealing a copy of the code, of course.) They won't even be able to guess that Z will happen to be 190-200 more often than 100-110. Instead, Z will be approximately evenly distributed between 100-200 all the time.

What algorithm would you use? You can't just reduce W to Y. (That would be predictable.)

You can't just pick a random number like 147. (No random numbers allowed here.)

I tried things like repeatedly taking W and divide it by 2... until it was between X and Y. (But I get far more 180-200 values for Z, than 100-120 values.... not "approximately evenly distributed" as desired.)

No big discussions about "true random numbers" or "pseudo random" numbers. Or exact definitions of "evenly distributed" or "approximately evenly distributed". A casual user would look at a 1000 examples of Z and just feel it was "close enough" to be considered "approximately evenly distributed".

This sounds similar to hashing algorithms. The principle behind hashing (and pseudo-random number generators) usually involves taking the modulus of a number to get a result evenly distributed between a range.

So for example, you could simply take W % 101 + 100 to get a number between 100 and 200. However, this would make Z very predictable because W+1 would map to Z+1 . To make the mapping less obvious, you might first multiply by an arbitrary factor, say 37 . This would give a result like:

W = 20141231
W * 37 = 745225547
W * 37 % 101 = 77
W * 37 % 101 + 100 = 177

One problem with using a small factor like 37 is that W + 1 maps to Z + 37 . If someone who is trying to guess the link would simply compare a bunch of consecutive values of W , the pattern might be obvious. So then you might use a confounding technique likely adding the sum of the digits in W (call it D ) and then setting the multiplication factor to (D + 37) :

W = 20141231
D = 2+0+1+4+1+2+3+1=14
F = 37 + D = 51
W * 51 = 1027202781
W * 51 % 101 + 100 = 157

You can invent any sort of arbitrary logic to apply to W to make it appear more "random", then apply the modulus of 101 to get a number in the range 100-200. Different techniques will result in more even or less even distribution, but you should be able to devise a technique that satisfies your requirements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM