← Назад к вопросам
FizzBuzz
1.0 Junior🔥 151 комментариев
Условие
Напишите программу, которая выводит числа от 1 до 100. При этом:
- Вместо чисел, кратных 3, выводите "Fizz"
- Вместо чисел, кратных 5, выводите "Buzz"
- Вместо чисел, кратных и 3, и 5, выводите "FizzBuzz"
Пример вывода
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16...
Дополнительные требования
- Сделать функцию, которая принимает число и возвращает результат
- Написать unit-тесты
- Сделать решение расширяемым (добавить другие делители)
Варианты реализации
- Классический if-else
- Через массив правил
- Через паттерн Strategy
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
FizzBuzz: Полное решение с расширяемостью
Решение 1: Классический if-else
function fizzBuzz(int $number): string
{
if ($number % 15 === 0) {
return 'FizzBuzz';
}
if ($number % 3 === 0) {
return 'Fizz';
}
if ($number % 5 === 0) {
return 'Buzz';
}
return (string)$number;
}
function printFizzBuzz(int $limit = 100): void
{
$result = [];
for ($i = 1; $i <= $limit; $i++) {
$result[] = fizzBuzz($i);
}
echo implode(', ', $result);
}
printFizzBuzz(100);
Проблема: Не расширяемо. Если добавить новое правило, нужно переписывать функцию.
Решение 2: Массив правил (рекомендуется)
class Rule
{
public function __construct(
private int $divisor,
private string $output
) {}
public function apply(int $number): ?string
{
return $number % $this->divisor === 0 ? $this->output : null;
}
}
class FizzBuzzGame
{
private array $rules = [];
public function __construct()
{
$this->addRule(new Rule(15, 'FizzBuzz'));
$this->addRule(new Rule(3, 'Fizz'));
$this->addRule(new Rule(5, 'Buzz'));
}
public function addRule(Rule $rule): self
{
$this->rules[] = $rule;
return $this;
}
public function evaluate(int $number): string
{
foreach ($this->rules as $rule) {
$result = $rule->apply($number);
if ($result !== null) {
return $result;
}
}
return (string)$number;
}
public function play(int $limit = 100): string
{
$results = [];
for ($i = 1; $i <= $limit; $i++) {
$results[] = $this->evaluate($i);
}
return implode(', ', $results);
}
}
$game = new FizzBuzzGame();
echo $game->play(100);
$game->addRule(new Rule(7, 'Whizz'));
Преимущества:
- Легко добавлять новые правила
- Легко тестировать отдельные правила
- Удовлетворяет принципу Open/Closed
Решение 3: Паттерн Strategy
interface FizzBuzzStrategy
{
public function evaluate(int $number): ?string;
}
class DivisibleStrategy implements FizzBuzzStrategy
{
public function __construct(
private int $divisor,
private string $output
) {}
public function evaluate(int $number): ?string
{
return $number % $this->divisor === 0 ? $this->output : null;
}
}
class DigitContainsStrategy implements FizzBuzzStrategy
{
public function __construct(
private string $digit,
private string $output
) {}
public function evaluate(int $number): ?string
{
return str_contains((string)$number, $this->digit) ? $this->output : null;
}
}
class FizzBuzzProcessor
{
private array $strategies = [];
public function addStrategy(FizzBuzzStrategy $strategy): self
{
$this->strategies[] = $strategy;
return $this;
}
public function process(int $number): string
{
$results = [];
foreach ($this->strategies as $strategy) {
$result = $strategy->evaluate($number);
if ($result !== null) {
$results[] = $result;
}
}
return !empty($results) ? implode('', $results) : (string)$number;
}
public function playGame(int $limit = 100): string
{
$output = [];
for ($i = 1; $i <= $limit; $i++) {
$output[] = $this->process($i);
}
return implode(', ', $output);
}
}
$processor = new FizzBuzzProcessor();
$processor->addStrategy(new DivisibleStrategy(3, 'Fizz'))
->addStrategy(new DivisibleStrategy(5, 'Buzz'))
->addStrategy(new DivisibleStrategy(7, 'Whizz'));
echo $processor->playGame(100);
Преимущества Strategy:
- Максимальная гибкость
- Легко создавать новые стратегии
- Можно комбинировать стратегии для одного числа
Unit-тесты
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
class FizzBuzzTest extends TestCase
{
private FizzBuzzGame $game;
protected function setUp(): void
{
$this->game = new FizzBuzzGame();
}
public function testReturnNumberIfNotDivisible(): void
{
$this->assertEquals('1', $this->game->evaluate(1));
$this->assertEquals('2', $this->game->evaluate(2));
$this->assertEquals('4', $this->game->evaluate(4));
}
public function testReturnFizzForDivisibleBy3(): void
{
$this->assertEquals('Fizz', $this->game->evaluate(3));
$this->assertEquals('Fizz', $this->game->evaluate(6));
$this->assertEquals('Fizz', $this->game->evaluate(9));
}
public function testReturnBuzzForDivisibleBy5(): void
{
$this->assertEquals('Buzz', $this->game->evaluate(5));
$this->assertEquals('Buzz', $this->game->evaluate(10));
$this->assertEquals('Buzz', $this->game->evaluate(20));
}
public function testReturnFizzBuzzForDivisibleBy15(): void
{
$this->assertEquals('FizzBuzz', $this->game->evaluate(15));
$this->assertEquals('FizzBuzz', $this->game->evaluate(30));
$this->assertEquals('FizzBuzz', $this->game->evaluate(45));
}
public function testPlayGeneratesCorrectSequence(): void
{
$expected = '1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz';
$result = $this->game->play(15);
$this->assertEquals($expected, $result);
}
public function testAddingCustomRule(): void
{
$this->game->addRule(new Rule(7, 'Whizz'));
$this->assertEquals('Whizz', $this->game->evaluate(7));
$this->assertEquals('Whizz', $this->game->evaluate(14));
}
}
Сравнение подходов
| Критерий | if-else | Массив правил | Strategy |
|---|---|---|---|
| Простота | ✓✓✓ | ✓✓ | ✓ |
| Расширяемость | ✗ | ✓✓✓ | ✓✓✓ |
| Тестируемость | ✓ | ✓✓✓ | ✓✓✓ |
| Гибкость | ✗ | ✓✓ | ✓✓✓ |
| Производительность | ✓✓✓ | ✓✓ | ✓ |
Рекомендация
Для интервью используй Решение 2 (Массив правил) потому что:
- Демонстрирует понимание SOLID принципов
- Легко объяснить и реализовать
- Достаточно гибко для расширения
- Хороший баланс между простотой и функциональностью
Итоговый результат
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, FizzBuzz...
Заключение: FizzBuzz демонстрирует знание принципов чистого кода, расширяемости и тестирования.
Похожие вопросы
- Развернуть строку без strrev
- Склонение слова программист
- Функция Фибоначчи
- Проверка на палиндром
- REST API генератор случайных чисел
- Поиск дубликатов в массиве
- Менеджер задач с ролями
- REST API для сущности Item (Laravel)
- Мини-блог на Laravel
- Сервис сокращения ссылок
- Реализация паттерна Singleton
- Сервис консультаций для абитуриентов
- REST API для авторов и книг
- Форма обратной связи с обработкой заявок
- Каталог товаров интернет-магазина
- Сервис управления задачами с API
- Загрузка больших файлов (1-N ГБ)
- Импорт большого XML файла в базу данных
- Параллельные вычисления на PHP
- Справочник организаций с геолокацией