Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## 2025-05-15 - Hybrid Sampling for Unique Random Numbers
**Learning:** Rejection sampling using a Set for unique random number generation suffers from the Coupon Collector's Problem, where performance degrades exponentially as the requested count approaches the range size due to increasing collisions.
**Action:** Implement a hybrid strategy: use rejection sampling for sparse requests (<50% of range) to save memory, and switch to an exclusion-based strategy (like a partial Fisher-Yates shuffle) for dense requests to ensure (Count)$ performance.

## 2025-05-15 - Avoid Cold Path Micro-optimizations
**Learning:** Optimizing one-time setup functions (e.g., platform detection using regex on `navigator.userAgent`) is a micro-optimization that adds code complexity without improving the user experience or solving a real bottleneck.
**Action:** Focus on "hot paths" (high-frequency loops, frequent event handlers, or heavy data processing) where performance gains are measurable and impactful.
35 changes: 26 additions & 9 deletions random.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,39 @@

<script>
function generateRandomNumbers() {
let minValue = parseInt(document.getElementById('minValue').value);
let maxValue = parseInt(document.getElementById('maxValue').value);
let count = parseInt(document.getElementById('count').value);
let randomNumbers = new Set();
const minValue = parseInt(document.getElementById('minValue').value);
const maxValue = parseInt(document.getElementById('maxValue').value);
const count = parseInt(document.getElementById('count').value);

if (isNaN(minValue) || isNaN(maxValue) || isNaN(count) || minValue >= maxValue || count <= 0 || count > (maxValue - minValue + 1)) {
const rangeSize = maxValue - minValue + 1;

if (isNaN(minValue) || isNaN(maxValue) || isNaN(count) || minValue >= maxValue || count <= 0 || count > rangeSize) {
document.getElementById('randomNumbers').innerText = '請確保輸入正確的數值範圍和數量';
return;
}

while (randomNumbers.size < count) {
let randomNumber = Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
randomNumbers.add(randomNumber);
let result = [];

// ⚡ Bolt: Use hybrid sampling to avoid the Coupon Collector's Problem.
// If requested count is high relative to range (> 50%), use exclusion sampling (array swap).
// Otherwise, use rejection sampling (Set) which is more memory efficient for sparse requests.
if (count > rangeSize / 2) {
const pool = Array.from({ length: rangeSize }, (_, i) => i + minValue);
for (let i = 0; i < count; i++) {
const j = Math.floor(Math.random() * (rangeSize - i)) + i;
[pool[i], pool[j]] = [pool[j], pool[i]];
}
result = pool.slice(0, count);
} else {
const randomNumbers = new Set();
while (randomNumbers.size < count) {
const randomNumber = Math.floor(Math.random() * rangeSize) + minValue;
randomNumbers.add(randomNumber);
}
result = Array.from(randomNumbers);
}

document.getElementById('randomNumbers').innerText = Array.from(randomNumbers).join(', ');
document.getElementById('randomNumbers').innerText = result.join(', ');
}
</script>
</body>
Expand Down