【问题标题】:Generate a 9 digit number with no more than 3 duplicate numbers生成一个不超过 3 个重复数字的 9 位数字
【发布时间】:2019-03-30 09:45:18
【问题描述】:

我正在尝试在 php 中创建一个类似刮刮卡的系统,该系统根据随机生成的数字显示赢家或输家。

我知道我可以使用 mt_rand 或 rand 创建一个 0-9 范围内的随机数,但我遇到的问题是确保 3 的重复项不超过一个

9 位数字输出 100% 没有匹配的数字或 9 位数字,一个数字最多出现 3 次,如 2948410427

我这样做的原因是我有很多主题卡片每个主题都有 10 个小图标这些图标编号为 0-9 网络用户打开我的应用程序它将随机选择一个主题然后发送请求到我的服务器有这个主题

然后服务器将生成数字,然后这些数字将像这样以 json 格式输出

{
    "Theme": "Space",
    "one": 3,
    "two": 6,
    "three": 0,
    "four": 7,
    "five": 1,
    "six": 3,
    "seven": 2,
    "eight": 9,
    "nine": 3,
    "winner": true
}

然后我的应用程序将使用这些数字链接到图像

1.png
2.png
3.png

等等填满划痕的网格。

这是我认为最好的方法,同时允许随机主题选择和随机获胜者。

如果有人能想到更好的方法,我会很高兴听到它。

【问题讨论】:

  • 将所有数字放在一个字符串中三次。使用str_shuffle,然后打印前9位。
  • 您需要跟踪绘制的数字并应用您在此处指定的逻辑
  • 应该每次运行创建一个具有三个相等数字的数字和另一个数字,还是应该是随机的事情,它是系列中的三个相等数字?
  • @Andreas 它应该生成一个随机的 9 位数字。但我想限制它,以便如果一个数字重复 3 次,它不会允许另一个数字或任何其他数字的重复次数超过两次,这样生成的每个 rumber 都是随机的,并且只有一个数字一次被 3 重复
  • 你没有回答我的问题

标签: php random scratchcard


【解决方案1】:

如果你洗牌和切片 3 次,切片 3 个值,那么你将得到 9 个值,并且最多只有 3 个值:

$array = range(1, 9);
$keys  = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');

shuffle($array);
$result = array_slice($array, 0, 3);
shuffle($array);
$result = array_merge($result, array_slice($array, 0, 3));
shuffle($array);
$result = array_merge($result, array_slice($array, 0, 3));

$result = array_combine($keys, $result);

我喜欢Severin Pappadeux's 的回答,有以下变化:

$array = array_merge($r = range(1, 9), $r, $r);
$keys  = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
shuffle($array);
$result = array_combine($keys, array_slice($array, 0, 9));

要检查 3 个相同的值,计数值并搜索 3:

if($v = array_search(3, array_count_values($result))) {
    echo "You won with $v"; // :-)
} else {
    echo "Loser";           // :-(
}

【讨论】:

  • 我对此进行了测试,我似乎每 5 次左右就会获得一次胜利,所以这似乎是一个不错的选择
  • 你知道我如何判断这是否包含中奖代码,还是我必须遍历数组并检查每个值是否有重复项,然后计算重复项?
  • 如何定义中奖代码?我没有在问题中看到这一点。
  • 不是你如何定义中奖代码 你如何判断创建的代码是否中奖,即包含 3 个相同的数字
  • 非常感谢你的神奇宝贝,当涉及到大部分 php 东西时,我并不是最好的
【解决方案2】:

在@AbraCadaver 的回答之后,怎么样(对不起,我的 PHP 很生锈)

$src  = array_merge($r=range(1, 9), $r, $r); /* 123456789123456789123456789 */
$keys = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');

shuffle($src);
$result = array_slice($src, 0, 9);

$result = array_combine($keys, $result);

所有组合都将被允许并平均分配最多 3 个重复数字

更新

刚刚尝试http://phptester.net 版本,其中初始数组有点不同,结果(在按下测试按钮 50 次左右后)可见有点不同。如果 shuffle() 实现的质量好的话……

$src = array_merge(range(1, 9), range(9, 1, -1), range(1, 9)); /* 123456789987654321123456789 */
print_r($src);
shuffle($src);
$result = array_slice($src, 0, 9);
print_r($result);

【讨论】:

  • 我比我更喜欢这个,但我会这样做$src = array_merge($r=range(1, 9), $r, $r);
  • @AbraCadaver 是的,绝对更好 - 只有一次呼叫范围。谢谢,答案已更新(我的最后一个 PHP 生产代码已有 10 多年的历史了......)
  • 看到这很奇怪,因为我注意到在上面提到的修改中使用此代码会产生很多双精度数,例如连续 88 或 55 或 22,因此键 1 和 2 将是相同的数字或密钥 5 和 6 将是相同的数字,而在运行它大约 40 次之后似乎并不经常发生我到目前为止一直坚持使用@AbraCadaver 第一个代码,并且我已经将它移植到 java 和 python 用于其他端口我的应用程序
  • @Dude2019 很有趣。我在初始化、洗牌和切片后添加了print_r(),并通过phptester.net 运行它,对我来说看起来不错(PHP 7)。但是,如果您对 @AbraCadaver 代码感到满意,那就这样吧 - 但我相信它会产生与我的统计不同的结果
  • @AbraCadaver 刚刚尝试了这个想法的另一种变体,请检查更新
【解决方案3】:

创建一个具有 2 x [0-9] 范围的基础。
添加一个随机数,然后将它们全部洗牌。

从数组中切出前九位数字并将它们连接起来以创建刮刮卡。

这意味着如果刮刮卡是中奖卡,它是随机的,并且它是随机的三个数字。

$base = array_merge(range(0,9), range(0,9));
$winning_number = [mt_rand(0,9)];

$all_numbers = array_merge($base, $winning_number);
shuffle($all_numbers);

$scratch_card = array_slice($all_numbers, 0,9);

echo join($scratch_card);

https://3v4l.org/NjItR

【讨论】:

  • 现在已经测试了大约 30 次,但没有显示一个获胜者,但我感觉用户可能会对获胜率感到恼火,所以我可能不得不重新考虑这一点
  • @Dude2019 你可以用随机数组替换winning_number。 $winning_number = range(mt_rand(0,9), mt_rand(0,9));。这是一个中奖次数的例子:3v4l.org/OdQP2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
相关资源
最近更新 更多