Write a function for r and 5() that returns a random int between 0 and 5, implement r and 7 ()
2026 Update: Modulo and Remainder Operations — Edge Cases and Applications
The modulo operation (%) is deceptively tricky for negative numbers and floats. Different languages handle it differently, causing subtle bugs in production code.
def modulo_demo():
"""Demonstrate Python's modulo behavior vs other languages."""
# Python: result has same sign as divisor (floor division)
print("Python modulo:")
print(f" 7 % 3 = {7 % 3}") # 1
print(f"-7 % 3 = {-7 % 3}") # 2 (NOT -1!)
print(f" 7 %-3 = {7 % -3}") # -2
print(f"-7 %-3 = {-7 % -3}") # -1
# C/Java: result has same sign as dividend (truncation division)
def c_modulo(a: int, b: int) -> int:
return int(a / b) * b # Truncation toward zero... wait
# Actually: result = a - b * trunc(a/b)
import math
def c_mod(a: int, b: int) -> int:
return a - b * math.trunc(a / b)
print("nC-style modulo:")
print(f" 7 mod 3 = {c_mod(7, 3)}") # 1
print(f"-7 mod 3 = {c_mod(-7, 3)}") # -1 (C behavior)
print(f" 7 mod-3 = {c_mod(7, -3)}") # 1
def circular_operations():
"""Practical uses of modulo in programming."""
# 1. Circular array / ring buffer
def next_index(current: int, size: int) -> int:
return (current + 1) % size
# 2. Day of week calculation (Zeller's congruence simplified)
def day_of_week(days_from_monday: int) -> str:
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
return days[days_from_monday % 7]
# 3. Check divisibility patterns
def is_divisible_by_9(n: int) -> bool:
"""Sum of digits divisible by 9 iff n divisible by 9."""
digit_sum = sum(int(d) for d in str(abs(n)))
return digit_sum % 9 == 0
# 4. Round to nearest multiple
def round_to_multiple(n: int, multiple: int) -> int:
return ((n + multiple // 2) // multiple) * multiple
print(f"5 days from Monday: {day_of_week(5)}") # Saturday
print(f"12 days from Monday: {day_of_week(12)}") # Saturday (12 % 7 = 5)
print(f"Is 918 divisible by 9? {is_divisible_by_9(918)}") # True (9+1+8=18)
print(f"Round 17 to nearest 5: {round_to_multiple(17, 5)}") # 15
circular_operations()
modulo_demo()
# Fast modulo for power of 2 (bitmask trick):
def fast_mod_power_of_2(n: int, k: int) -> int:
"""n % 2^k using bitwise AND (faster than % operator)."""
mask = (1 << k) - 1 # 2^k - 1 = 0b111...1 (k ones)
return n & mask
print(f"100 % 8 = {100 % 8}") # 4
print(f"100 & 7 = {fast_mod_power_of_2(100, 3)}") # 4 (same result, faster)
Modulo pitfalls in production:
- Hash table indexing: Always use
abs(hash) % size— hash values can be negative in Python - Negative timestamps: Unix epoch goes negative for pre-1970 dates; floor modulo matters
- Ring buffer indexing:
(head - 1) % capacitycan be negative in C++ — use(head - 1 + capacity) % capacity - Cryptographic modulo: Python’s
pow(base, exp, mod)uses fast modular exponentiation — don’t manually compute large modulos
💡Strategies for Solving This Problem
Rejection Sampling
Classic random number generation problem. Got this at Google. It's about using one random source to create another with different properties.
The Problem
Given rand5() which returns random int 0-4 uniformly, implement rand7() which returns random int 0-6 uniformly.
Why It's Tricky
Can't just do rand5() + rand5() or rand5() % 7 - these don't give uniform distribution.
Key Insight: Generate Larger Range
Call rand5() twice to get random number 0-24:
result = rand5() * 5 + rand5()
This gives 25 equally-likely outcomes. Since 25 = 3×7 + 4, use first 21 outcomes for rand7(), reject 22-24.
Rejection Sampling
- Generate candidate from larger space
- If in valid range, return it
- Otherwise, try again
Ensures uniform distribution because we only accept equally-likely outcomes.
Expected Calls
Probability of acceptance: 21/25 = 0.84
Expected calls to rand5(): 2 / 0.84 ≈ 2.38
General Pattern
To implement randN() using randM():
- Find k such that M^k >= N
- Generate number 0 to M^k - 1
- Take largest multiple of N that fits
- Reject and retry if outside