Как написать 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 fizzBuzzWhen() {
    for (it in 1..100) {
        when {
            it % 15 == 0 -> {
                println("Fizz Buzz = $it")
                continue
            }
            it % 5 == 0 -> {
                println("Buzz = $it")
                continue
            }
            it % 3 == 0 -> {
                println("Fizz = $it")
                continue
            }
            else -> println("$it")
        }
    }
}

Мда… Читаемость стала хуже, и строчек прибавилось… Давайте перепишем нашу функцию, позаимствовав фичи из 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

Ответить

Ваш адрес email не будет опубликован.