Как бы переделал реализацию рандомайзера для значений true и false, чтобы она генерировала случайные числа 1, 2, 3?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Рефакторинг рандомайзера boolean в генератор чисел
Если изначально имеется реализация, генерирующая случайные значения true/false, и её нужно адаптировать для генерации чисел 1, 2, 3, потребуется внести несколько ключевых изменений в логику работы. Рассмотрим поэтапный процесс рефакторинга.
1. Анализ исходной реализации
Предположим, исходный код выглядел примерно так:
class BooleanRandomizer {
public function generate(): bool {
return mt_rand(0, 1) === 1;
}
public function generateMultiple(int $count): array {
$results = [];
for ($i = 0; $i < $count; $i++) {
$results[] = $this->generate();
}
return $results;
}
}
Эта реализация использует равномерное распределение между двумя значениями через сравнение с 1.
2. Стратегии переработки
Для генерации чисел 1, 2, 3 нужно:
A. Прямая модизация метода generate()
Самый простой подход — изменить логику генерации:
class NumberRandomizer {
public function generate(): int {
return mt_rand(1, 3);
}
}
B. Расширение функциональности через параметры
Более гибкое решение с конфигурируемым диапазоном:
class ConfigurableRandomizer {
private int $min;
private int $max;
public function __construct(int $min = 1, int $max = 3) {
$this->min = $min;
$this->max = $max;
}
public function generate(): int {
return mt_rand($this->min, $this->max);
}
}
// Использование
$randomizer = new ConfigurableRandomizer(1, 3);
$value = $randomizer->generate(); // 1, 2 или 3
C. Реализация через стратегию
Паттерн "Стратегия" для поддержки разных распределений:
interface RandomizationStrategy {
public function generate(): int;
}
class UniformDistributionStrategy implements RandomizationStrategy {
private int $min;
private int $max;
public function __construct(int $min, int $max) {
$this->min = $min;
$this->max = $max;
}
public function generate(): int {
return mt_rand($this->min, $this->max);
}
}
class WeightedDistributionStrategy implements RandomizationStrategy {
private array $weights;
public function __construct(array $weights) {
$this->weights = $weights;
}
public function generate(): int {
$total = array_sum($this->weights);
$random = mt_rand(1, $total);
foreach ($this->weights as $number => $weight) {
$random -= $weight;
if ($random <= 0) {
return $number;
}
}
return array_key_first($this->weights);
}
}
// Использование с равномерным распределением
$uniform = new UniformDistributionStrategy(1, 3);
$value = $uniform->generate();
// Использование с взвешенным распределением (например, 1:20%, 2:30%, 3:50%)
$weighted = new WeightedDistributionStrategy([1 => 20, 2 => 30, 3 => 50]);
$value = $weighted->generate();
3. Криптографически безопасная альтернатива
Для приложений, требующих криптографической безопасности:
class SecureRandomizer {
private int $min;
private int $max;
public function __construct(int $min = 1, int $max = 3) {
$this->min = $min;
$this->max = $max;
}
public function generate(): int {
$range = $this->max - $this->min;
$bits = ceil(log($range + 1, 2));
$bytes = ceil($bits / 8);
do {
$random = hexdec(bin2hex(random_bytes($bytes)));
$value = $random % ($range + 1);
} while ($random - $value > (PHP_INT_MAX - $range));
return $value + $this->min;
}
}
4. Тестирование и валидация
После рефакторинга важно протестировать распределение:
class RandomizerTest {
public function testDistribution(RandomizationStrategy $randomizer, int $iterations = 10000): array {
$results = [];
for ($i = 0; $i < $iterations; $i++) {
$value = $randomizer->generate();
$results[$value] = ($results[$value] ?? 0) + 1;
}
foreach ($results as $value => $count) {
$results[$value] = $count / $iterations * 100;
}
return $results;
}
}
// Проверка равномерности распределения
$randomizer = new UniformDistributionStrategy(1, 3);
$distribution = (new RandomizerTest())->testDistribution($randomizer);
// Ожидаем ~33.3% для каждого значения
5. Рекомендации по реализации
-
Выбор ГСЧ:
mt_rand()достаточно для большинства задачrandom_int()для криптографической безопасности
-
Инкапсуляция логики: Лучше вынести генерацию в отдельный класс с интерфейсом
-
Расширяемость: Предусмотреть возможность изменения диапазона и распределения
-
Производительность: Для bulk-генерации можно оптимизировать:
class BulkRandomizer {
public function generateBatch(int $count, int $min = 1, int $max = 3): array {
$results = [];
for ($i = 0; $i < $count; $i++) {
$results[] = mt_rand($min, $max);
}
return $results;
}
}
Таким образом, переход от генерации boolean к числам 1-3 требует изменения типа возвращаемого значения и логики выбора случайного элемента из множества трёх значений вместо двух. Наиболее правильным подходом будет создание гибкой, тестируемой системы с чёткими интерфейсами и поддержкой различных сценариев использования.