Порівняння рішень на Java, Kotlin та Scala

Давайте розглянемо, як задачу https://leetcode.com/problems/relative-ranks/solutions/6326961/sorting-mapping-approach можна вирішити трьома мовами програмування — Java, Kotlin та Scala.

Проблема: Знаходимо відносні ранги

Маючи масив балів (int[] score), необхідно присвоїти ранги, як-от "Золота медаль", "Срібна медаль" та "Бронзова медаль" для трьох найкращих, а іншим гравцям — числовий ранг. Основна мета — написати оптимальний і зрозумілий код.

Рішення на Java: Класика, потужність, боілерплейт

class Solution {
    public String[] findRelativeRanks(int[] score) {
        int[] sorted =
                Arrays.stream(score)
                        .boxed()
                        .sorted(Collections.reverseOrder())
                        .mapToInt(Integer::intValue)
                        .toArray();

        Map<Integer, Integer> rankMap = new HashMap<>();
        for (int i = 0; i < sorted.length; i++) {
            rankMap.put(sorted[i], i);
        }

        return Arrays.stream(score)
                .mapToObj(individualScore -> {
                    int rank = rankMap.get(individualScore);
                    return switch (rank) {
                        case 0 -> "Gold Medal";
                        case 1 -> "Silver Medal";
                        case 2 -> "Bronze Medal";
                        default -> String.valueOf(rank + 1);
                    };
                })
                .toArray(String[]::new);
    }
}

Java може здатися дещо громіздкою, особливо для роботи з колекціями.

Другий пункт коду, де ми створюємо rankMap, реалізований у імперативному стилі. Java, на жаль, не має синтаксичних конструкцій, які дозволили б виразно та читабельно написати цю частину декларативно. Тому я обрав імперативний підхід, щоб забезпечити чіткість та простоту логіки.

Рішення на Kotlin: Сучасний підхід

class Solution {
    fun findRelativeRanks(score: IntArray): Array<String> {
        val rankMap =
            score.sortedArrayDescending()
                .withIndex()
                .associate { (index, value) -> value to index }

        return score.map { mapScoreToRank(it, rankMap) }.toTypedArray()
    }

    private fun mapScoreToRank(score: Int, rankMap: Map<Int, Int>): String {
        return when (val index = rankMap.getValue(score)) {
            0 -> "Gold Medal"
            1 -> "Silver Medal"
            2 -> "Bronze Medal"
            else -> (index + 1).toString()
        }
    }
}

Переваги Kotlin:

  • Зрозумілі трансформації: Функції sortedArrayDescending і withIndex роблять процес сортування й індексації простим.

  • Мінімум шуму: Здатність Kotlin виводити типи автоматично скорочує код.

  • Логічний поділ: Хелпер mapScoreToRank додає ясності.

Рішення на Scala: Елегантність функціонального підходу

Scala виводить лаконічність на новий рівень, пропонуючи компактні й виразні рішення:

object Solution {
  def findRelativeRanks(score: Array[Int]): Array[String] = {
    val rankMap =
      score.sorted(Ordering[Int].reverse)
        .zipWithIndex
        .toMap
    score.map(rankMap.andThen(indexToRank))
  }

  private val indexToRank: Int => String = {
    case 0 => "Gold Medal"
    case 1 => "Silver Medal"
    case 2 => "Bronze Medal"
    case i => (i + 1).toString
  }
}

Особливості Scala:

  • Ланцюжки трансформацій: Функції zipWithIndex і toMap створюють лаконічний і зрозумілий код.

  • Вищі функції: Композиція через andThen додає елегантності.
    Мене вразив Scala тим, що можна комбінувати Map і функцію rankMap.andThen(indexToRank). У інших мовах функцію можна композувати лише з іншою функцією.

  • Патерн-матчинг: Дозволяє перетворювати ранги у медалі або числа без зайвих деталей.

Scala ідеально підходить для тих, хто захоплюється функціональним підходом до програмування.

Порівняння продуктивності

Усі три рішення мають схожі етапи: сортування, мапування й форматування результатів. Основна складність визначається операцією сортування (O(n log n)), що забезпечує ефективність у всіх випадках. Вибір мови зводиться до особистих уподобань та досвіду команди.

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Edgar
Edgar@avuzi

Back-end розробник Java Kotlin

10Прочитань
1Автори
0Читачі
На Друкарні з 12 грудня

Більше від автора

Вам також сподобається

  • 5 уроків, які я виніс з 2 півотів на Scrimmage

    Коли ви робите інвестиції, кожен ваш грошовий рух вимірюється і перевіряється, але коли ви робите ставки на спорт, ви покладаєтеся тільки на своє внутрішнє чуття, чому так? Чому б нам не змінити це і не дати кожному гравцю на спортивних ставках силу інвестора?

    Теми цього довгочиту:

    Стартап
  • Тестова документація

    Кожен тестувальник регулярно використовує тестову документацію, завдяки ній тестувальник спілкується з розробниками, завдяки ній тестувальник знає що і коли робити.

    Теми цього довгочиту:

    Qa

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається

  • 5 уроків, які я виніс з 2 півотів на Scrimmage

    Коли ви робите інвестиції, кожен ваш грошовий рух вимірюється і перевіряється, але коли ви робите ставки на спорт, ви покладаєтеся тільки на своє внутрішнє чуття, чому так? Чому б нам не змінити це і не дати кожному гравцю на спортивних ставках силу інвестора?

    Теми цього довгочиту:

    Стартап
  • Тестова документація

    Кожен тестувальник регулярно використовує тестову документацію, завдяки ній тестувальник спілкується з розробниками, завдяки ній тестувальник знає що і коли робити.

    Теми цього довгочиту:

    Qa