← Назад к вопросам
FizzBuzz
2.2 Middle🔥 191 комментариев
#JavaScript Core
Условие
Напишите функцию fizzBuzz(n), которая выводит числа от 1 до n с заменами.
Требования
- Для чисел, кратных 3, выводить "Fizz"
- Для чисел, кратных 5, выводить "Buzz"
- Для чисел, кратных и 3, и 5, выводить "FizzBuzz"
- Для остальных чисел выводить само число
Примеры
fizzBuzz(15);
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
fizzBuzz(5);
// 1, 2, Fizz, 4, Buzz
Бонус
Сделайте функцию настраиваемой - чтобы можно было передать правила замены: fizzBuzz(n, { 3: "Fizz", 5: "Buzz", 7: "Bazz" })
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
FizzBuzz — классическая задача на собеседованиях, проверяющая логику условий и способность обобщать код. Решим её в несколько уровней сложности.
Базовое решение
Прямолинейный подход с условными операторами:
function fizzBuzz(n: number): string[] {
const result: string[] = [];
for (let i = 1; i <= n; i++) {
// Проверяем делимость на 15 первой (это и 3, и 5)
if (i % 15 === 0) {
result.push("FizzBuzz");
} else if (i % 3 === 0) {
result.push("Fizz");
} else if (i % 5 === 0) {
result.push("Buzz");
} else {
result.push(i.toString());
}
}
return result;
}
console.log(fizzBuzz(15).join(", "));
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
Анализ:
- Временная сложность: O(n)
- Пространственная сложность: O(n)
- Главное: проверить 15 перед 3 и 5, иначе будет неправильно
Улучшенное решение: Конкатенация
Более элегантный способ без многоуровневых условий:
function fizzBuzzConcat(n: number): string[] {
const result: string[] = [];
for (let i = 1; i <= n; i++) {
let output = "";
// Собираем строку из частей
if (i % 3 === 0) output += "Fizz";
if (i % 5 === 0) output += "Buzz";
// Если ничего не добавили, используем число
result.push(output || i.toString());
}
return result;
}
Преимущества:
- Легче добавлять новые правила
- Меньше вложенности if-else
- Более читаемый код
Бонус: Настраиваемая версия
Передаём правила в виде объекта:
interface FizzBuzzRules {
[key: number]: string;
}
function fizzBuzzCustom(
n: number,
rules: FizzBuzzRules = { 3: "Fizz", 5: "Buzz" }
): string[] {
const result: string[] = [];
const sortedDivisors = Object.keys(rules)
.map(Number)
.sort((a, b) => a - b); // Сортируем делители
for (let i = 1; i <= n; i++) {
let output = "";
// Проходим по всем делителям в порядке возрастания
for (const divisor of sortedDivisors) {
if (i % divisor === 0) {
output += rules[divisor];
}
}
result.push(output || i.toString());
}
return result;
}
// Использование
console.log(fizzBuzzCustom(15).join(", "));
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
console.log(fizzBuzzCustom(21, { 3: "Fizz", 5: "Buzz", 7: "Bazz" }).join(", "));
// 1, 2, Fizz, 4, Buzz, Fizz, Bazz, 8, Fizz, Buzz, 11, Fizz, 13, Bazz, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz
Продвинутое решение: Функциональный стиль
Используем map и функции высшего порядка:
function fizzBuzzFunctional(
n: number,
rules: FizzBuzzRules = { 3: "Fizz", 5: "Buzz" }
): string[] {
const divisors = Object.keys(rules).map(Number);
const lcm = divisors.reduce((a, b) =>
(a * b) / gcd(a, b), 1
);
return Array.from({ length: n }, (_, i) => {
const num = i + 1;
const output = divisors
.filter(d => num % d === 0)
.map(d => rules[d])
.join("");
return output || num.toString();
});
}
function gcd(a: number, b: number): number {
return b === 0 ? a : gcd(b, a % b);
}
Тестирование
// Базовые случаи
console.log(fizzBuzz(5).join(", "));
// 1, 2, Fizz, 4, Buzz
console.log(fizzBuzz(15).join(", "));
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
// Граничные случаи
console.log(fizzBuzz(1));
// ["1"]
console.log(fizzBuzz(0));
// []
Сравнение подходов
| Подход | Гибкость | Читаемость | Сложность | Масштабируемость |
|---|---|---|---|---|
| Базовое | Низкая | Средняя | O(n) | Плохая |
| Конкатенация | Средняя | Высокая | O(n) | Хорошая |
| Настраиваемое | Высокая | Хорошая | O(n*m) | Отличная |
| Функциональное | Высокая | Средняя | O(n*m) | Отличная |
Рекомендации для собеседования
- Начните с базового решения — покажите понимание задачи
- Подумайте о порядке проверок — 15 перед 3 и 5 важен
- Предложите улучшение — конкатенация более элегантна
- Обсудите бонус — настраиваемость показывает опыт
- Объясните трейд-офф — гибкость vs простота
Для реального проекта используйте конкатенацию или настраиваемую версию — они более поддерживаемы и масштабируемы.