Случайным образом выбираем, кому дать бутылку пива: Пете, Васе или Ивану.
Но вероятность получения бутылки пива у каждого человека разная - у Пети 10%, и Васи 60%, а у Ивана 30% (человек может быть от двух до десяти).
Как выбрать счастливчика? В болшинстве случаев пивко получать будет Вася, но иногда радость выпадет и для Ивана с Петей.
Если можно то напишите и код ;)
function get_winner($a)
{
......
return $winner;
}
$a = array("Petya" => 10, "Vasya" => 60, "Ivan" => 30);
$name = get_winner($a); // "Vasya"
$name = get_winner($a); // "Vasya"
$name = get_winner($a); // "Ivan"
$name = get_winner($a); // "Vasya"
$name = get_winner($a); // "Petya"
$a = array("Petya" => 50, "Vasya" => 50);
$name = get_winner($a); // "Petya"
$name = get_winner($a); // "Petya"
$name = get_winner($a); // "Vasya"
// и так далее
Спустя 4 минуты, 19 секунд (25.08.2011 - 12:07) linker написал(а):
Как-то так
$pivo = rand(1, 100);но правда слишком утрировано.
if ($pivo <= 10)
echo 'Дать Пете';
else
if ($pivo > 10 && $pivo <= 70)
echo 'Дать Васе';
else
if ($pivo > 70)
echo 'Дать Ивану';
Спустя 3 минуты, 56 секунд (25.08.2011 - 12:11) alexfbm написал(а):
linker, спасибо конечно, до такого варианта я и сам додумался, но в данном примере не катит
Кол-во людей разное и на входе я не знаю цифр 10 и 70.
Обновил свой пост, посмотри что на входе имеется.

Обновил свой пост, посмотри что на входе имеется.
Спустя 54 минуты, 4 секунды (25.08.2011 - 13:05) linker написал(а):
А всё просто, если за 100% взять значение 100, то у Пети 10% - будет значение 10, у Васи 60% - 60 (Петя + 60 = 70), у Ивана 30% - 30 (Вася + 30 = 100). А дальше думай.
Спустя 49 минут, 18 секунд (25.08.2011 - 13:55) alexfbm написал(а):
Походу написал функцию, по крайней мере сколько не тестил, все работает правильно.
function get_winner($a)
{
$winner = false;
// proverjaem, verni li vhodnie dannie (summa procentov dolzhna bitj 100%)
$check_percent = 0;
foreach ($a as $v) {
$check_percent += $v;
}
if ($check_percent == 100)
{
// esli neskolko ljudej imeejut odin i tot zhe procent, to sortiruem imenno etih ljudej randomom.
uasort ($a, function ($a, $b){
if ($a == $b) {
$vals = array(-1, 1);
return $vals[array_rand($vals)];
}
elseif ($a > $b) {
return 1;
}
return 0;
});
//sortiruem v porjadke ubivanija (po procentu)
arsort($a);
// vichisljaem pobeditelja
$rand_nr = rand(1,100);
$a_original = $a;
$i = 1;
$prev = 0;
foreach ($a as $k=>$v)
{
$next = next($a_original);
if ($next > 0)
{
if ($i == 1){
if ($rand_nr <= $v) {
$winner = $k;
break;
}
}
else {
if ($rand_nr >= $prev && $rand_nr <= (100 - $next)) {
$winner = $k;
break;
}
}
$prev = $v;
}
else {
if ($rand_nr >= (100 - $v)) {
$winner = $k;
break;
}
}
$i++;
}
}
return $winner;
}
$a = array("Petya" => 10, "Vasya" => 60, "Ivan" => 30);
//$a = array("Petya" => 20, "Vasya" => 80);
//$a = array("Petya" => 50, "Vasya" => 50);
//$a = array("Petya" => 10, "Vasya" => 20, "Ivan" => 30, "Sasha"=>20, "Oleg" =>20);
//$a = array("Petya" => 100, "Vasya" => 0);
//$a = array("Petya" => 100);
$name = get_winner($a);
Спустя 29 минут, 30 секунд (25.08.2011 - 14:24) linker написал(а):
А у меня примерно так получилось
function winner($mens)
{
$lastMax = 0;
$val = rand(1, 100);
foreach($mens as $name => $percent)
{
$count = $percent * 100/100;
$max = $count + $lastMax;
if ($val >= $lastMax && $val <= $max)
return $name;
}
}
echo winner(array('Петя' => 10, 'Вася' => 60, 'Иван' => 30));
Спустя 13 минут (25.08.2011 - 14:37) alexfbm написал(а):
linker
не рабоает - функция часто возвращает пустоту. Провертьте с моими примерами.
не рабоает - функция часто возвращает пустоту. Провертьте с моими примерами.
Спустя 2 минуты (25.08.2011 - 14:39) linker написал(а):
У меня пока ещё ни разу пустоты не выдало.
Спустя 4 минуты (25.08.2011 - 14:43) alexfbm написал(а):
Цитата (linker @ 25.08.2011 - 11:39) |
У меня пока ещё ни разу пустоты не выдало. |
F5 понажимайте в браузере.. у меня уже после третьего раза выдало пустоту.
Спустя 32 секунды (25.08.2011 - 14:44) linker написал(а):
Да, забыл один момент
$lastMax = $max;т.е. должно быть так
function winner($mens)
{
$lastMax = 0;
$val = rand(1, 100);
foreach($mens as $name => $percent)
{
$count = $percent * 100/100;
$max = $count + $lastMax;
if ($val >= $lastMax && $val <= $max)
return $name;
$lastMax = $max;
}
}
echo winner(array('Петя' => 10, 'Вася' => 60, 'Иван' => 30));
Спустя 2 минуты, 4 секунды (25.08.2011 - 14:46) linker написал(а):
Если в цикле
$res = array();то вроде примерно честное распределение получается.
for($i = 0; $i < 100; ++ $i)
{
$name = winner(array('Петя' => 10, 'Вася' => 60, 'Иван' => 30));
if (isset($res[$name]))
++ $res[$name];
else
$res[$name] = 1;
}
print_r($res);
Спустя 7 минут, 19 секунд (25.08.2011 - 14:53) alexfbm написал(а):
Да, все верно теперь у вас работает. Я так же проверил и свой пример в цикле, результаты одинаковые, тоже честно распределяет. Но у вас реализация более элегантная)