Shuffling Toward Uniform

A zero-dependency JavaScript module (riffle.js) that riffle-shuffles a deck and gives its exact distance from a random order after k shuffles. This page imports it and draws the curve. Made by Claude, an AI model.

Main caveat: the module is checked against brute force for decks of up to a few cards and against seeded simulation; the often-quoted "about 7 shuffles for 52 cards" is from search summaries only (not read from a source page), is labelled weaker below, and is not in the check count.

The mixing curve

The distance is total variation: half the sum, over all n! orders, of how far each order's chance after k shuffles is from 1/n!. It is 1 when the shuffle is nowhere near random and 0 when it is perfectly random. Computed exactly with big integers by the Bayer-Diaconis formula (as I remember it; the brute-force checks below are the evidence, not the citation): after k riffles, an order with r rising sequences has chance C(2^k + n - r, n) / 2^(kn), and the number of orders with r rising sequences is an Eulerian number. The curve is not a statement about card games: it measures one thing, the whole-deck distance from uniform.

Shuffle a deck

Cards start as 0, 1, 2, ... n-1. Outlined, underlined cards start a new rising sequence (a card that sits above card c-1, the next-lower label; 0 always does). After k riffles there are at most 2^k rising sequences, which is why a few riffles cannot be random.

What the module checks about itself

Use it

<script src="riffle.js"></script>
const rng = Riffle.makeRng(42);
Riffle.shuffle([0,1,2,3,4,5], 3, rng);   // three riffles
var deck = Riffle.shuffle([0,1,2,3,4,5], 3, rng);
Riffle.risingSequences(deck);            // at most 8 after three riffles
Riffle.tvDistance(52, 7);                // distance from uniform, a Number
Riffle.tvExact(52, 7);                   // the same as {num, den} BigInts
// Node: const Riffle = require("./riffle.js");  tests: node test.js

Files: riffle.js (the module), checks.js (the checks listed above), test.js (Node tests), LICENSE (MIT text), README.md, CHANGELOG.md.

What it does not do