Implement Rand10 Using Rand7

To solve this coding challenge, we'll leverage the existing
rand7()
API, which provides a uniform random integer from 1 to 7, in order to create a new function
rand10()
that outputs a uniform random integer from 1 to 10. The key challenge here is converting the output range of a uniform random number generator efficiently without introducing significant bias.

Explanation

Here's an in-depth explanation of the methodology we'll employ:
  1. Understanding rand7() Output : The
    rand7()
    function returns any integer from 1 to 7, each number having an equal probability of 1/7.
  2. Expanding the Range Multiplicatively : By calling
    rand7()
    twice, we can simulate a larger range of numbers.
    • The first call to
      rand7()
      gives us an integer from 1 to 7.
    • The second call to
      rand7()
      gives us another integer from 1 to 7.
      To fully utilize these results, we think of the first call as choosing a row and the second call as choosing a column in a 7x7 grid, creating a total of 49 possible outcomes (7*7).
  3. Mapping 49 Outcomes to a Useful Range : Since we want a range from 1 to 10:
    • Generate a number between 1 and 49. Each of these 49 outcomes should have equal probability.
    • Use only the first 40 outcomes and map them evenly to 1-10. The remaining 9 outcomes (41-49) are discarded, and we repeat the process until we get a valid number within 1-40.
  4. Dividing and Modulo Operation : By leveraging modulo operations, we can map the 40 outcomes to the desired range of 1-10.
  5. Pseudocode with Comments

    The pseudocode below describes the detailed steps to solve this problem:
                                                
    function rand10():
    while True:
    # Generate a number in the range [1, 49]
    num = (rand7() - 1) * 7 + rand7()
    
    # If the number lies within the first 40 outcomes, map it to [1, 10]
    if num <= 40:
    return num % 10 + 1
    # If the number is outside [1, 40], discard and repeat
    
                                            
    The pseudocode efficiently maps the outputs of
    rand7()
    to an equivalent uniform distribution over the desired range [1, 10]. Here's a breakdown of the inner workings:
  6. Generate Extended Range :
    • (rand7() - 1) * 7 + rand7()
      effectively creates a number in [1, 49].
    • rand7() - 1
      creates a range of [0, 6]. Multiplying by 7 shifts this base by increments of 7.
    • Adding another
      rand7()
      call within that extended range gives us all possible combinations in [1, 49].
  7. Discard Unfit Values :
    • The condition
      if num <= 40
      ensures only the first 40 numbers are considered, thus maintaining uniform distribution when mapping to [1, 10].
    • If
      num
      falls within [41, 49], it is discarded, and the loop continues until a valid number in [1, 40] is produced, ensuring fairness in the final mapping step.
  8. Modulo and Offset :
    • num % 10
      maps values in the set {1-40} directly to sets {0-9}, and adding 1 shifts this to {1-10}.

    Detailed Steps in Pseudocode

  9. Initiate Loop :
    • Continue until a valid number (within 1-40) is found.
  10. First randomized number :
    • (rand7() - 1) * 7
      : Maps rand7() to multiples of 7 (0, 7, 14, ..., 42).
  11. Second randomized number :
    • Add a second
      rand7()
      result to span [1, 49].
  12. Check Validity :
    • Confirm if within 1-40. If not, repeat.
  13. Return Mapped Result :
    • Use modulo operation and adjust range to return a number between 1 and 10.
By repeatedly generating numbers until a fit within the desired subset is found and using modulo to map these evenly, the approach ensures each possible output from
rand10()
is equally probable.