random number generation
rand7 from rand5
algorithm
probability
computer science

Compute rand7 using rand5

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

The challenge of creating a function rand7() using rand5() is a classic problem in computer science that involves generating a uniform distribution over a range of integers using another random generator with a different range. In this case, we aim to generate a random integer from 1 to 7 using a function that can only generate random integers from 1 to 5. This problem is significant because it exemplifies techniques used in randomness and probability manipulation—skills that are essential in simulation, cryptographic applications, and algorithm design.

Technical Explanation

Understanding rand5()

rand5() is a given function that returns uniformly random integers between 1 and 5, inclusive. This means that each integer from 1 to 5 has an equal probability of 1/51/5 of being chosen.

Building rand7() from rand5()

The goal is to construct rand7(), which outputs integers from 1 to 7 with equal likelihood. Given rand5() generates five possible outcomes, a single call to rand5() doesn't provide enough different outcomes to map 1-to-1 to 7 outcomes while maintaining uniformity. Therefore, we must use multiple calls to rand5() judiciously.

The core idea: Simulating a larger range

To effectively achieve this, we combine multiple calls to rand5() to simulate a larger range. Here are the main steps used in our implementation:

  1. Generate a number in a larger range: By calling rand5() twice, we can simulate numbers from 1 to 25 (5 * (rand5() - 1) + rand5()), offering a 25-length space. We utilize this range because 25≥725 \geq 7 is a multiple.
  2. Mapping to 1-7: We want to divide this 25-space into equally probable 7-length blocks. However, since 25mod  7≠025 \mod 7 \neq 0, we have some leftover numbers beyond three complete 7-length blocks (a total of 21 numbers).
  3. Eliminating bias: To eliminate bias, if the generated number is in [1, 21], we map it straight to 1 through 7. If not, we discard it and re-call the function.

Implementation

Here is an implementation in pseudocode:

plaintext
1function rand7():
2    while True:
3        num = 5 * (rand5() - 1) + rand5()  # This gives us a uniform number from 1 to 25
4        if num <= 21:
5            return (num % 7) + 1
  • Explanation: By iterating until the generated number is within the first 21, we ensure each of 1, 2, ..., 7 have an equal probability of 1/71/7.

Analysis and Discussion

Why does this work?

The rejection sampling technique causes the non-uniform probability space (from 22 to 25) to be sampled infrequently enough to not affect the uniformity for numbers 1 through 21. Essentially, we ignore the overflow that would introduce bias by sampling until we get a suitable outcome.

Expected Performance

The efficiency of this algorithm depends on the average number of rand5() calls required:

  • Probability of success in one loop iteration: 21/2521/25.
  • Expected number of tries (geometric distribution): Given by ∑k=1∞k⋅p⋅(1−p)k−1\sum_{k=1}^{\infty} k \cdot p \cdot (1-p)^{k-1} where p=21/25p = 21/25, yielding ≈1.19\approx 1.19 iterations on average.

Considerations and Limitations

  • Tradeoff between randomness and efficiency: The method achieves true randomness. However, there is a calculable tradeoff between correctness and performance, as this method can take multiple loops at worst.
  • In any practical large-scale implementation, pseudo-randomness suffices for generating single-time random integer sequences. However, mathematical rigor as discussed here is crucial.

Summary Table

Here's a table summarizing key points of this approach:

AspectDetails
Input FunctionalityGenerates random number between 1 and 5 using rand5().
Output FunctionalityProvides a random number between 1 and 7.
TechniqueCombined rand5() calls to simulate more outcomes. Mapped numbers to desired range using rejection sampling.
Success Probability21/2521/25 for each loop iteration.
Average IterationsApproximately 1.19 iterations per valid output.
Complexity and ConsiderationO(1) average case Trade-offs between unpredictability and performance.

The detailed explanation above outlines the feasibility and elegance of generating a uniform random number range with an initially limited-functionality generator, highlighting essential concepts in computer science regarding randomness and probability distribution.


Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms