Привет, Хабр! Меня зовут Леонид Иванькин, я ведущий Android-разработчик в МТС Digital, работаю над приложением Мой МТС. В этой статье – сложные и не очень задачи, чтобы проверить, насколько хорошо вы разбираетесь в операторах для списков. Готовы испытать свои скиллы? Тогда переходите под кат!
При разработке на Kotlin часто приходится использовать списки (List, MutableList и другие), а также операторы для них. Каждый раз, заходя в документацию, я убеждаюсь, что операторов очень много, а в их использовании есть тонкости.
Многие коллеги говорят, что в этой теме они разбираются на 100%. Давайте проверим, насколько хорошо вы владеете операторами для списков. Я подготовил 14 логических задач разной сложности, попробуйте их решить.
Ставлю на то, что даже опытные разработчики справятся не со всеми задачами, несмотря на кажущуюся простоту 🙂
Правила
Есть задание — лист элементов. Ваша задача вставить один оператор, чтобы получилось значение в комментариях, которое стоит после знака =. В данной задаче это 1.
listOf(1, 3, 3, 2, 4, 1) //missed operator .let { println(it) }//=1
Решение здесь тривиальное: нужно взять первый элемент, чтобы получить 1. Применив, например, оператор first().
listOf(1, 3, 3, 2, 4, 1) .first() .let { println(it) }//=1
Надеюсь, что правила понятны.
Замечания и допущения
-
Хочу отметить, что из-за разнообразия операторов и по стечению обстоятельств решений может быть несколько. Например, для задачи выше также правильными были бы решения last(), get(0) и так далее.
-
Во всех задачах использован один и тот же список.
-
Не нужно во всех задачах искать логику с точки зрения решения бизнес-задач. Иногда задачи нарочно составлены с ошибками с точки зрения адекватности, сбивающими с толку.
-
Эти упражнения помогут вам не только размять свой мозг, но и узнать о некоторых особенностях операторов, с которыми вы, возможно, не сталкивались.
-
Задачи я старался располагать от простых к сложным. Но при решении нужно учитывать, что у каждого свой уровень и опыт.
-
Ответы к задачам – в конце статьи, но не спешите скроллить вниз!
-
Не переживайте, если вы не смогли решить все задачи. Они придуманы именно для того, чтобы заставить вас поломать голову. Я сам не смог бы решить их все 🙂
Итак, приступим.
Задачи
Легкий уровень
Начнем с легких задач. Обратите внимание, что во всех задачах массив одинаковый listOf(1, 3, 3, 2, 4, 1)
Задача 1.
listOf(1, 3, 3, 2, 4, 1) //missed operator .let { println(it) }//=6
Задача 2.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=5
Задача 3.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=14
Задача 4.
listOf(1, 3, 3, 2, 4, 1) //missed operator .average() .let { println(it) }//=2.5
Обратите внимание, что оператор sum() поменялся. Теперь нужно искать не сумму, а среднее значение. В последующих задачах оператор также будет меняться или вовсе пропадать
Задача 5.
listOf(1, 3, 3, 2, 4, 1) //missed operator .average() .let { println(it) }//=8.0
Средний уровень
Эти задачи будут чуть посложнее и более каверзные.
Задача 6.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=8
Задача 7.
listOf(1, 3, 3, 2, 4, 1) //missed operator .let { println(it) }//=72
Задача 8.
listOf(1, 3, 3, 2, 4, 1) //missed operator .let { println(it) }//=null
Задача 9.
listOf(1, 3, 3, 2, 4, 1) //missed operator .let { println(it) }//=kotlin.Unit
Задача 10.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=15
Задача 11.
listOf(1, 3, 3, 2, 4, 1) //missed operator .first() .let { println(it) }//=java.util.NoSuchElementException
Сложный уровень
Напоследок 3 довольно сложные (с моей точки зрения) задачи.
Задача 12.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=29
Задача 13.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=27
Задача 14.
listOf(1, 3, 3, 2, 4, 1) //missed operator .sum() .let { println(it) }//=6
Замечание: это должен быть не subList().
Ответы
Задача 1.
listOf(1, 3, 3, 2, 4, 1) .count() .let { println(it) }//=6
В этой задаче легко догадаться, что в массиве 6 элементов. Чтобы получить это число, нужно воспользоваться оператором count().
Задача 2.
listOf(1, 3, 3, 2, 4, 1) .takeLast(2) .sum() .let { println(it) }//=5
В этой задаче также наглядно видно, что последние 2 числа в сумме дают 5.
Задача 3.
listOf(1, 3, 3, 2, 4, 1) .map { it } .sum() .let { println(it) }//=14
Это, скорее, задача-шутка, так как тут ничего не нужно делать со списком, чтобы получить в ответе 14. Но в условии сказано, что нужно добавить один оператор. Оператор, который ничего не делает, – это map { it }. Другие решения типа also{}, let{it} также принимаются.
Задача 4.
listOf(1, 3, 3, 2, 4, 1) .distinct() .average() .let { println(it) }//=2.5
Здесь ищем среднее значение из неповторяющихся элементов. Тут было бы уместно начать с подсчета среднего значения – сначала у исходного массива, а далее понять, что нужно каким-то способом это значение уменьшать.
Задача 5.
listOf(1, 3, 3, 2, 4, 1) .map { 8 } .average() .let { println(it) }//=8.0
Тут тоже задача-шутка. Сразу понятно, что среднее из текущего листа никак не получить. Один из способов — заменить все числа на необходимые.
Задача 6.
listOf(1, 3, 3, 2, 4, 1) .filterIndexed { index, value -> index % 2 == 0 } .sum() .let { println(it) }//=8
В этом случае находим сумму из чисел с четными индексами, то есть из списка listOf(1, 2, 4).
Задача 7.
listOf(1, 3, 3, 2, 4, 1) .fold(1) { acc, x -> acc * x } .let { println(it) }//=72 //or listOf(1, 3, 3, 2, 4, 1) .reduce { acc, x -> acc * x } .let { println(it) }//=72
Тут из числа 72 видно, что ожидается большой ответ. Также стоит отметить, что нет оператора sum(). Самый быстрый способ найти решение – начать перемножать. Этого можно достичь с помощью операторов fold() и reduce().
Задача 8.
listOf(1, 3, 3, 2, 4, 1) .getOrNull(7) .let { println(it) }//=null
В этой задаче нужно было вернуть null. Самый простой способ это сделать — использовать те операторы, которые в наименовании имеют …OrNull(), и подставить туда необходимые для этого условия. Например, вернуть число с индексом больше, чем есть в списке.
Задача 9.
listOf(1, 3, 3, 2, 4, 1) .forEach { } .let { println(it) }//=kotlin.Unit
В этой задаче решение состоит в том, чтобы вернуть значение от оператора, который ничего не возвращает, например forEach { }.
Задача 10.
listOf(1, 3, 3, 2, 4, 1) .indices .sum() .let { println(it) }//=15
В этой задаче нужно сложить сумму индексов.
Задача 11.
listOf(1, 3, 3, 2, 4, 1) .take(0) .first() .let { println(it) }//=java.util.NoSuchElementException
Эта задача похожа на задачу 8. То есть нужно каким-то способом вернуть то, чего нет в списке, а конкретно – первый элемент. Так как тут стоит именно first(), а не firstOrNull(), то возникнет ошибка. Простой способ сделать список пустым — это take(0).
Задача 12.
listOf(1, 3, 3, 2, 4, 1) .mapIndexed { index, value -> index + value } .sum() .let { println(it) }//=29
В данном случае находится сумма всех чисел и их индексов.
Задача 13.
listOf(1, 3, 3, 2, 4, 1) .flatMap { 0.rangeTo(it) } .sum() .let { println(it) }//=27
Эта задача довольно сложная. Здесь нужно вернуть сумму каждого значения в списке и его предшествующим, начиная с 1. То есть для 1: 1, для 3: 1+ 2+ 3, для 2: 1+ 2 и так далее.
Задача 14.
listOf(1, 3, 3, 2, 4, 1) .distinctBy { it % 3 } .sum() .let { println(it) }//=6
Эта задача, с моей точки зрения, самая сложная. До ее решения непросто догадаться. Тут нужно найти сумму уникальных чисел, но не всех, а меньше 4. Уникальных чисел у нас всего 4: 1, 2, 3, 4. Однако остаток от деления на 3 у числа 4 равен 1. Так же как и у 1. Поэтому число 4 исключается из списка.
Заключение
Ученый-информатик Дональд Кнут утверждает, что решение логических задач выделяет гормоны, которые повышают уровень счастья. Надеюсь, с вами это произошло!
Поделитесь в комментариях – удалось ли вам решить все задачи? Возможно, вы нашли что-то новое, чего раньше знали об операторах, либо не придавали этому значения?
Если вы заметили ошибку, также напишите в об этом комментариях. Там же вы можете предложить более интересные решения, если их удалось найти.
ссылка на оригинал статьи https://habr.com/ru/company/ru_mts/blog/674040/
Добавить комментарий