List Shuffle Distribution Test

This regression test checks whether a fixed 10-item list is distributed across the 10 output positions as expected over 100,000 Fisher-Yates shuffles.

What was tested?

  • Input: labels A through J.
  • Runs: 100,000 independent shuffles.
  • Expected count: 10,000 appearances for each item-position pair.
  • Algorithm: Fisher-Yates.
  • Random integer mapping: 32-bit cryptographic values with rejection sampling.
  • Environment: Node.js cryptographic random bytes, run on September 23, 2026.

What did the test find?

The largest absolute difference from the expected 10,000 appearances was 281, or 2.81% of the expected cell count. Every row and column still totals 100,000 observations by construction. The result is consistent with ordinary sampling variation, but it is not a proof or independent certification of randomness.

ItemP1P2P3P4P5P6P7P8P9P10
A9910100979919990210168993999799935997010181
B99061028110027999898491000099631009199039982
C98321002499011002610017100251001510009102079944
D1007999449897994610040100581002410021100949897
E998298171011610015990799881004110087993310114
F1004610003100669944100331006499079924995110062
G100009954997599531013410008100539884101039936
H101051001910009100759990994310064997398939929
I10177988210072101749885995199591011899109872
J99639979100189967997710024999599581003610083

How can I reproduce it?

The repository command is npm run test:distribution. The test implementation is stored in scripts/randomization-distribution-test.js. A fresh run will produce different counts because it uses fresh random input, but the JSON output retains the same fields for comparison.

What are the limitations?

This run tests a 10-item position distribution and the documented Fisher-Yates/rejection-sampling path. It does not certify operating-system entropy, every browser, every list size, or the completeness of a contest entry list. Regulated drawings and security-sensitive systems require the process specified by their governing rules.