<?php
// your code goes here
function randomFactory
(array $data): Closure
{ $values = [];
$rand = 0;
foreach ($data as $value => $chance) {
$values[] = [
'rand' => $rand += $chance,
'value' => $value,
];
}
return function () use ($values) {
$rand = random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
foreach ($values as $value) {
if ($rand < $value['rand']) {
return $value['value'];
}
}
throw new LogicException('smth get wrong');
};
}
$data = [
1 => 0.1,
2 => 0.25,
3 => 0.25,
4 => 0.4,
];
$random = randomFactory($data);
$attempts = 10000;
for ($i = 0; $i < $attempts; ++$i) {
$rand = $random();
++$result[$rand];
}
echo "value\tcount\texpected\treal\tdiff", PHP_EOL, PHP_EOL;
foreach ($result as $value => $count) {
$real = $count / $attempts;
$diff = abs($real - $data[$value]); printf("%d\t%5d\t%8.2f\t%.2f\t%.2f" . PHP_EOL
, $value, $count, $data[$value], $real, $diff); }
PD9waHAKCi8vIHlvdXIgY29kZSBnb2VzIGhlcmUKZnVuY3Rpb24gcmFuZG9tRmFjdG9yeShhcnJheSAkZGF0YSk6IENsb3N1cmUgewogICAgJHZhbHVlcyA9IFtdOwogICAgJHJhbmQgPSAwOwogICAgZm9yZWFjaCAoJGRhdGEgYXMgJHZhbHVlID0+ICRjaGFuY2UpIHsKICAgICAgICAkdmFsdWVzW10gPSBbCiAgICAgICAgICAgICdyYW5kJyA9PiAkcmFuZCArPSAkY2hhbmNlLAogICAgICAgICAgICAndmFsdWUnID0+ICR2YWx1ZSwKICAgICAgICBdOwogICAgfQoKICAgIHJldHVybiBmdW5jdGlvbiAoKSB1c2UgKCR2YWx1ZXMpIHsKICAgICAgICAkcmFuZCA9IHJhbmRvbV9pbnQoMCwgUEhQX0lOVF9NQVgpIC8gUEhQX0lOVF9NQVg7CiAgICAgICAgZm9yZWFjaCAoJHZhbHVlcyBhcyAkdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCRyYW5kIDwgJHZhbHVlWydyYW5kJ10pIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdmFsdWVbJ3ZhbHVlJ107CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRocm93IG5ldyBMb2dpY0V4Y2VwdGlvbignc210aCBnZXQgd3JvbmcnKTsKICAgIH07Cn0KCiRkYXRhID0gWwogICAgMSA9PiAwLjEsCiAgICAyID0+IDAuMjUsCiAgICAzID0+IDAuMjUsCiAgICA0ID0+IDAuNCwKXTsKJHJhbmRvbSA9IHJhbmRvbUZhY3RvcnkoJGRhdGEpOwoKJHJlc3VsdCA9IGFycmF5X2NvbWJpbmUoYXJyYXlfa2V5cygkZGF0YSksIGFycmF5X2ZpbGwoMCwgY291bnQoJGRhdGEpLCAwKSk7CiRhdHRlbXB0cyA9IDEwMDAwOwpmb3IgKCRpID0gMDsgJGkgPCAkYXR0ZW1wdHM7ICsrJGkpIHsKICAgICRyYW5kID0gJHJhbmRvbSgpOwogICAgKyskcmVzdWx0WyRyYW5kXTsKfQoKZWNobyAidmFsdWVcdGNvdW50XHRleHBlY3RlZFx0cmVhbFx0ZGlmZiIsIFBIUF9FT0wsIFBIUF9FT0w7CmZvcmVhY2ggKCRyZXN1bHQgYXMgJHZhbHVlID0+ICRjb3VudCkgewogICAgJHJlYWwgPSAkY291bnQgLyAkYXR0ZW1wdHM7CiAgICAkZGlmZiA9IGFicygkcmVhbCAtICRkYXRhWyR2YWx1ZV0pOwogICAgcHJpbnRmKCIlZFx0JTVkXHQlOC4yZlx0JS4yZlx0JS4yZiIgLiBQSFBfRU9MLCAkdmFsdWUsICRjb3VudCwgJGRhdGFbJHZhbHVlXSwgJHJlYWwsICRkaWZmKTsKfQ==