← Назад к вопросам
FizzBuzz
1.0 Junior🔥 271 комментариев
#Коллекции и структуры данных#Язык Swift
Условие
Напишите функцию на Swift, которая выводит числа от 1 до N со следующими правилами:
- Если число делится на 3, вместо числа выводится "Fizz"
- Если число делится на 5, вместо числа выводится "Buzz"
- Если число делится и на 3, и на 5, вместо числа выводится "FizzBuzz"
- В остальных случаях выводится само число
Пример для N = 15:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
Требования:
- Функция должна возвращать массив строк
- Оптимальное использование оператора % (остаток от деления)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Подход
Это классическая задача на практику условных операторов и операции остатка от деления. Ключевой момент — правильный порядок проверок: сначала нужно проверить делимость и на 3, и на 5 одновременно, потом на 3, затем на 5, и только потом возвращать само число.
Основное решение
func fizzBuzz(_ n: Int) -> [String] {
var result: [String] = []
for i in 1...n {
if i % 3 == 0 && i % 5 == 0 {
result.append("FizzBuzz")
} else if i % 3 == 0 {
result.append("Fizz")
} else if i % 5 == 0 {
result.append("Buzz")
} else {
result.append(String(i))
}
}
return result
}
Элегантное решение со строкой
Альтернативный подход — построить строку из условных частей:
func fizzBuzzElegant(_ n: Int) -> [String] {
return (1...n).map { i -> String in
var output = ""
if i % 3 == 0 {
output += "Fizz"
}
if i % 5 == 0 {
output += "Buzz"
}
return output.isEmpty ? String(i) : output
}
}
Этот вариант изящнее, так как:
- Используется
mapдля трансформации диапазона - Не нужно проверять
i % 15 == 0— строка автоматически конкатенируется - Код более читаемый и maintainable
Оптимизированное решение с capacity
Если N очень большое, можно зарезервировать память:
func fizzBuzzOptimized(_ n: Int) -> [String] {
var result: [String] = []
result.reserveCapacity(n) // Зарезервируем память для N элементов
for i in 1...n {
var output = ""
if i % 3 == 0 {
output += "Fizz"
}
if i % 5 == 0 {
output += "Buzz"
}
result.append(output.isEmpty ? String(i) : output)
}
return result
}
Тестирование
let result = fizzBuzz(15)
print(result.joined(separator: ", "))
// Output: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz
let result2 = fizzBuzz(5)
print(result2.joined(separator: ", "))
// Output: 1, 2, Fizz, 4, Buzz
let result3 = fizzBuzz(30)
// Проверяем, что 30 дает FizzBuzz
print(result3[29]) // FizzBuzz
Почему второе решение лучше
Преимущества:
- Меньше проверок: Вместо трёх условных ветвей делаем две независимые проверки
- Масштабируемость: Легко добавить новое правило (например, "Jazz" на 7). Просто добавляем ещё один
ifблок - Читаемость: Логика очевидна — добавляем слово в строку, если число делится
- Функциональный стиль: Использует
map, что соответствует парадигме Swift
Сложность:
- Время: O(n) — каждое число обрабатывается один раз
- Память: O(n) — результирующий массив размером N
Кейсы для обсуждения на интервью
- Что произойдёт, если N = 0 или отрицательное? Нужно ли обрабатывать?
- Как масштабировать, если правил будет 10+? (Можно использовать словарь чисел → строк)
- Производительность при N = 1 000 000?
Рекомендация
На интервью выбирайте второе решение (со строкой и map) — оно демонстрирует понимание функционального программирования в Swift и лучше масштабируется.