← Назад к вопросам

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

Почему второе решение лучше

Преимущества:

  1. Меньше проверок: Вместо трёх условных ветвей делаем две независимые проверки
  2. Масштабируемость: Легко добавить новое правило (например, "Jazz" на 7). Просто добавляем ещё один if блок
  3. Читаемость: Логика очевидна — добавляем слово в строку, если число делится
  4. Функциональный стиль: Использует map, что соответствует парадигме Swift

Сложность:

  • Время: O(n) — каждое число обрабатывается один раз
  • Память: O(n) — результирующий массив размером N

Кейсы для обсуждения на интервью

  • Что произойдёт, если N = 0 или отрицательное? Нужно ли обрабатывать?
  • Как масштабировать, если правил будет 10+? (Можно использовать словарь чисел → строк)
  • Производительность при N = 1 000 000?

Рекомендация

На интервью выбирайте второе решение (со строкой и map) — оно демонстрирует понимание функционального программирования в Swift и лучше масштабируется.