Skip to content

fix(ui): replace biased array shuffle with Fisher-Yates algorithm#846

Open
NewCoder3294 wants to merge 1 commit intokoala73:mainfrom
NewCoder3294:fix/biased-shuffle-algorithm
Open

fix(ui): replace biased array shuffle with Fisher-Yates algorithm#846
NewCoder3294 wants to merge 1 commit intokoala73:mainfrom
NewCoder3294:fix/biased-shuffle-algorithm

Conversation

@NewCoder3294
Copy link
Contributor

Summary

  • Replace biased array.sort(() => Math.random() - 0.5) with a proper Fisher-Yates (Knuth) shuffle in the search modal's tip randomization (SearchModal.ts line 301).
  • Add a reusable shuffle<T>() utility to src/utils/index.ts that returns a new array without mutating the original.
  • No other instances of the biased sort pattern were found elsewhere in the codebase.

Why this matters

Using sort() with a random comparator produces statistically biased results. The ECMAScript spec does not define a particular sorting algorithm, so the distribution of permutations depends on the engine's implementation (e.g., V8 uses TimSort). A random comparator violates the requirement that the comparator be consistent and transitive, meaning some orderings appear significantly more often than others.

The Fisher-Yates shuffle (also known as the Knuth shuffle) guarantees a uniformly random permutation in O(n) time by iterating backwards through the array and swapping each element with a randomly chosen element from the remaining unprocessed portion.

Changes

File Change
src/utils/index.ts Add generic shuffle<T>(arr: T[]): T[] utility function
src/components/SearchModal.ts Import shuffle from utils; replace tips.sort(() => Math.random() - 0.5) with shuffle(tips)

Test plan

  • TypeScript compiles cleanly (tsc --noEmit)
  • Verify search modal empty state still shows 4 randomized tips when opened
  • Confirm tips appear in varying order across multiple opens

🤖 Generated with Claude Code

The search modal tip randomization used `array.sort(() => Math.random() - 0.5)`
which produces statistically biased results because comparison-based sorting
algorithms require a consistent comparator to work correctly. A random comparator
violates this contract, causing some permutations to appear more frequently than
others depending on the underlying sort implementation.

Replace with a proper Fisher-Yates (Knuth) shuffle that guarantees a uniform
distribution of all possible permutations in O(n) time. The new `shuffle()`
utility is added to `src/utils/index.ts` for reuse across the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 2, 2026

@NewCoder3294 is attempting to deploy a commit to the Elie Team on Vercel.

A member of the Team first needs to authorize it.

@koala73 koala73 added Ready to Merge PR is mergeable, passes checks, and adds value Low Value Trivial, unnecessary, or not aligned with project needs labels Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Low Value Trivial, unnecessary, or not aligned with project needs Ready to Merge PR is mergeable, passes checks, and adds value

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants