这个难题的目的是拿出52张纸牌并洗牌,以使每张纸牌处于随机位置。
鉴于:
deck
代表卡片的52个不同整数组成的数组。当您开始时,deck
仅以未知顺序包含每张卡中的一张。- 函数,该函数
int rand(min, max)
返回insmin
和max
(含)之间的随机整数。您可以假定此函数是真正随机的。 - 一种功能,
void swap(x, y)
可以交换卡片组中的两张卡。如果您致电swap(x, y)
,则这些卡将在位置x
,y
并将切换位置。
什么时候:
- 程序调用
shuffle()
(或shuffle(deck)
,deck.shuffle()
或者您的实现喜欢运行),
然后:
deck
应该完全随机地包含每张卡中的一张。
抓住:
您不能声明任何变量。随心所欲地调用swap
和rand
,但是您不能声明自己的任何变量。这包括for
循环计数器-甚至是隐式计数器(如)foreach
。
说明:
- 您可以更改次要详细信息以适合您选择的语言。例如,您可以编写
swap
以通过引用切换两个整数。所做的更改应该是使它与您的语言配合使用,而不是使难题变得更容易。 deck
可以是全局变量,也可以将其作为参数。- 您可以对的内容进行任何操作
deck
,但不能更改其长度。 - 您的卡可以编号为0-51、1-52或您喜欢的任何编号。
- 您可以用任何一种语言编写此代码,但不会欺骗您的语言的内置
shuffle
功能。 - 是的,您可以在同一行中编写52次。没有人会留下深刻的印象。
- 执行时间并不重要,但真正的随机性却很重要。
- 这并不是真正的代码高尔夫球,但是请随时最小化/混淆您的代码。
编辑:样板代码和可视化工具
如果您使用.NET或JavaScript,以下一些测试代码可能会有用:
JavaScript:
- 带有JavaScript脚本源的快速,肮脏的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张卡片没有重复。然后,可视化工具绘制最终出现在牌组中每个位置的每张卡的频率,显示灰度热图。
可视化器的输出应看起来像没有明显图案的雪。显然,它不能证明真正的随机性,但这是一种快速简便的抽查方法。我建议使用它或类似的东西,因为混洗算法中的某些错误会导致输出中的模式很容易识别。这是两个实现的输出示例,一个实现有一个常见缺陷:
有缺陷的版本确实会部分打乱甲板,因此如果您手动检查阵列,可能会看起来不错。可视化器使您更容易注意到图案。
deck
。
swap
,只要满足基本目的,您就可以假设自己喜欢的任何实现。我做出建议swap
的部分原因是,人们可以将其视为“魔术”并专注于主要问题,而不必担心它会以他们选择的语言工作。您可以这样做,也可以自己编写swap
,这取决于您。