Как написать FizzBuzz на Kotlin

Привет! Сегодня будет небольшая заметка про FizzBuzz. Недавно наткнулся на статью на Хабре под названием «FizzBuzz, или почему программисты не умеют программировать«. Там автор сокрушался о том, что многие программисты при приеме на работу не способы решить тривиальные задания с использованием циклов, рекурсии и т.д.

В качестве одного из примеров приводилась известная задача по написанию программы FizzBuzz, которая выводит числа от 1 до 100. По словам автора, этот простой способ для того, чтобы отфильтровывать кандидатов.

Задача FizzBuzz решение

Итак, условие гласит: «Нужно написать программу, выводящую на экран числа в пределах от 1 до 100. Если число будет кратно 3, то вместо него вывести Fizz, а если число кратно пяти — слово Buzz. При этом, если число будет кратно 15, то вывести строку Fizz Buzz». Напишем простое решение

fun fizzBuzz() {
    for (n in 1..100){
        if(n % 15 == 0) {
            println("Fizz Buzz = $n")
            continue
        } else if (n % 5 == 0) {
            println("Buzz = $n")
            continue
        } else if (n % 3 == 0) {
            println("Fizz = $n")
            continue
        }
        println("$n")
    }
}

Результат выполнения — то что надо!

1
2
Fizz = 3
4
...

Готово! Но это решение не единственное. К примеру в Kotlin можно использовать оператор when

fun fizzBuzzWhwn(n: Int) = 
    when {
        n % 15 == 0 -> "FizzBuzz"
        n % 5 == 0 -> "Buzz"
        n % 3 ==0 -> "Fizz"
        else -> n
    }

Создадим Range (диапазон), и проверим результат

(1..100).map {
    println( fizzBuzzWhen(it))
}

1
2
Fizz
4
Buzz
...

Неплохо. Код отлично сократился, да и читаемость заметно улучшилась. А теперь давайте перепишем нашу функцию, позаимствовав фичи из Java 8.

fun fizzBuzzJava() = IntStream.rangeClosed(1, 100)
    .mapToObj { num: Int -> if (num % 3 == 0)
        if (num % 5 == 0) "Fizz Buzz = $num"
        else "Fizz = $num"
        else if (num % 5 == 0) "Buzz = $num"
        else num
    }
    .forEach { x: Serializable? -> println(x) }

Теперь разберем что да как. Одним из основных нововведений в Java 8 являются потоки — Streams. IntStream — один из интерфейсов Stream для работы с примитивами. Зачем он нужен, если хватило бы одного? Как написано в доках Stream API — примитивные «стримы» быстрее.

При помощи метода rangeClosed() создаем необходимый набор цифр от 1 до 100. Далее метод mapToObj() возвращает новый поток Stream, в котором к каждому элементу мы применяем промежуточные операции. Далее при помощи стандартного forEach выводим каждый элемент потока в консоль.

Кстати, в Kotlin тоже есть потоки — Flow, с которыми можно работать при использовании корутин. Этот способ разберем в одной из следующих статей

Код из статьи на GitHub — FizzBuzz

Один комментарий

  1. Я думаю, что тут можно добавить еще одно решение.
    ——

Оставить ответ