The object of this puzzle is to take a deck of 52 cards and shuffle it so that each card is in a random position.
Given:
- An array,
deck
, of 52 distinct integers representing the cards. When you start,deck
contains exactly one of each card in some unknown order. - A function,
int rand(min, max)
, that returns a random integer between intsmin
andmax
, inclusive. You can assume that this function is truly random. - A function,
void swap(x, y)
that swaps two cards in the deck. If you callswap(x, y)
, the cards at positionsx
andy
will switch places.
When:
- The program calls
shuffle()
(orshuffle(deck)
ordeck.shuffle()
or however your implementation likes to run),
Then:
deck
should contain exactly one of each card in perfectly random order.
The Catch:
You can't declare any variables. Call swap
and rand
as much as you like, but you can't declare any variables of your own. This includes for
loop counters--even implicit ones like in a foreach
.
Clarifications:
- You can change minor details to suit your chosen language. For example, you can write
swap
to switch two integers by reference. Changes should be to make this work with your language, not to make the puzzle easier. deck
can be a global variable, or you can take it in as a parameter.- You can do anything you want to the contents of
deck
, but you can't change its length. - Your cards can be numbered 0-51, 1-52, or anything you like.
- You can write this in any language, but no cheating with your language's built-in
shuffle
function. - Yes, you could write the same line 52 times. No one will be impressed.
- Execution time doesn't matter, but true randomness does.
- This isn't really code golf, but feel free to minimize/obfuscate your code.
Edit: Boilerplate code and visualizer
If you used .NET or JavaScript, here's some test code you may find useful:
JavaScript:
- Quick-and-dirty JavaScript visualizer, with CoffeeScript source: https://gist.github.com/JustinMorgan/3989752bdfd579291cca
- Runnable version (just paste in your
shuffle()
function): http://jsfiddle.net/4zxjmy42/
C#:
- ASP.NET visualizer with C# codebehind: https://gist.github.com/JustinMorgan/4b630446a43f28eb5559
- Stub with just the
swap
andrand
utility methods: https://gist.github.com/JustinMorgan/3bb4e6b058d70cc07d41
This code sorts and shuffles the deck several thousand times and performs some basic sanity testing: For each shuffle, it verifies that there are exactly 52 cards in the deck with no repeats. Then the visualizer plots the frequency of each card ending up at each place in the deck, displaying a grayscale heat map.
The visualizer's output should look like snow with no apparent pattern. Obviously it can't prove true randomness, but it's a quick and easy way to spot-check. I recommend using it or something like it, because certain mistakes in the shuffling algorithm lead to very recognizable patterns in the output. Here's an example of the output from two implementations, one with a common flaw:
The flawed version does partially shuffle the deck, so might look fine if you examined the array by hand. The visualizer makes it easier to notice a pattern.
deck
itself. \$\endgroup\$swap
you like, as long as it fulfills its basic purpose. Part of my reason for makingswap
a given was so that people could treat it as 'magic' and concentrate on the main problem without having to worry about it working in their language of choice. You can either do that or write your ownswap
, it's up to you. \$\endgroup\$