このパズルの目的は、52枚のカードのデッキを取り、各カードがランダムな位置になるようにシャッフルすることです。
与えられた:
deck
カードを表す52個の異なる整数の配列。開始時にdeck
は、不明な順序で各カードが1枚ずつ含まれています。int rand(min, max)
intmin
との間のランダムな整数を返す関数max
。この関数は本当にランダムであると仮定できます。void swap(x, y)
デッキ内の2枚のカードを交換する機能。を呼び出すswap(x, y)
と、カードの位置x
と位置y
が切り替わります。
いつ:
- プログラム呼び出し
shuffle()
(shuffle(deck)
またはdeck.shuffle()
または実装が実行したい場合)。
次に:
deck
完全にランダムな順序で各カードを正確に1つ含める必要があります。
キャッチ:
変数を宣言することはできません。swap
とrand
を好きなだけ呼び出しますが、独自の変数を宣言することはできません。これもfor
ループカウンターがますforeach
。
明確化:
- 選択した言語に合わせてマイナーな詳細を変更できます。たとえば、次のように書くことができます
swap
参照によって2つの整数を切り替えるます。変更は、パズルを簡単にするためではなく、あなたの言語でこの作業を行うべきです。 deck
グローバル変数にすることも、パラメーターとして受け取ることもできます。- あなたは何でもやりたいことができます
deck
、その長さは変更できません。 - カードには、0〜51、1〜52などの番号を付けることができます。
- これは任意の言語で記述できますが、言語の組み込み
shuffle
関数をごまかすことはできません。 - はい、同じ行を52回書くことができます。誰も感動しません。
- 実行時間は重要ではありませんが、真のランダム性は重要です。
- これは実際にはゴルフのコードではありませんが、コードを最小化/難読化してください。
編集:定型コードとビジュアライザー
.NETまたはJavaScriptを使用している場合、次のテストコードが役立ちます。
JavaScript:
- CoffeeScriptソースを使用した手軽なJavaScriptビジュアライザー:https : //gist.github.com/JustinMorgan/3989752bdfd579291cca
- 実行可能バージョン(
shuffle()
関数に貼り付けるだけ):http : //jsfiddle.net/4zxjmy42/
C#:
- C#コードビハインドを備えたASP.NETビジュアライザー:https ://gist.github.com/JustinMorgan/4b630446a43f28eb5559
swap
およびrand
ユーティリティメソッドのみを使用したスタブ:https : //gist.github.com/JustinMorgan/3bb4e6b058d70cc07d41
このコードは、デッキを数千回並べ替えてシャッフルし、いくつかの基本的な健全性テストを実行します。各シャッフルについて、繰り返しのないデッキに正確に52枚のカードがあることを確認します。次に、ビジュアライザーがデッキの各場所で終わる各カードの頻度をプロットし、グレースケールのヒートマップを表示します。
ビジュアライザーの出力は、明らかなパターンのない雪のように見えるはずです。明らかに、真のランダム性を証明することはできませんが、スポットチェックを行うための迅速かつ簡単な方法です。シャッフリングアルゴリズムの特定のミスが出力に非常に認識可能なパターンをもたらすため、このようなものを使用することを推奨します。次に、2つの実装からの出力の例を示します。1つには一般的な欠陥があります。
欠陥のあるバージョンはデッキを部分的にシャッフルするため、アレイを手作業で調べた場合は問題なく見えるかもしれません。ビジュアライザーを使用すると、パターンを簡単に認識できます。
deck
。
swap
、基本的な目的を達成する限り、基本的にあなたが好きな実装を想定できるということです。swap
与えられた私の理由の一部は、人々がそれを「魔法」として扱い、選択した言語で動作することを心配することなく主要な問題に集中できるようにすることでした。あなたはそれをするか、自分swap
で書くことができます、それはあなた次第です。