подсчет пар в списке

#algorithm #kotlin #mutablemap

#алгоритм #kotlin #изменяемая карта

Вопрос:

Я недавно начал работать с HackerRank и пытаюсь «Продажи по совпадению». Я пришел к решению, которое меня устраивает с точки зрения использования возможностей функционального программирования Kotlin. Однако я не получаю ожидаемого ответа…

Краткое описание проблемы:

Учитывая массив: -> найти и вернуть общее количество пар.

то есть:

-> ввод [10, 20, 20, 10, 10, 30, 50, 10, 20]

-> количество пар 3


вот мой код и некоторые комментарии, объясняющие его:

 fun sockMerchant(n: Int, pile: Array<Int>): Int{
    var count = 0
    mutableMapOf<Int, Int>().withDefault { 0 }.apply {
        // the [attempted] logic behind this piece of code here is 
        // that as we iterate through the list, the 'getOrPut()'
        // function will return either the value for the given [key]             
        // or throw an exception if there is no such key
        // in the map. However, since our map was created by 
        // [withDefault], the function resorts to its `defaultValue` <-> 0
        // instead of throwing an exception.
        for (e in values) {
            // this simplifies our code and inserts a zero [ 1] where needed.
            // if (key exists)
            //      // return its associated value and MOD it:
            //      case: even  -> increment counter
            //            else  -> do nothing
            // else if (key dne)
            //      // insert default value <-> [0]   1
            //              ....
            //              ....
            //              ....
            if (getOrPut(e, { getValue(e)   1 } ) % 2 == 0) count  
        }
    }
    return count
}


fun main(args: Array<String>) {
    val scan = Scanner(System.`in`)
    val n = scan.nextLine().trim().toInt()
    val ar = scan.nextLine().split(" ").map{ it.trim().toInt() }.toTypedArray()
    val result = sockMerchant(n, ar)
    println(result)
}
  


Любая помощь или советы будут иметь большое значение здесь 🙂

Комментарии:

1. Что означает n переменная?

2. Кроме того, в вашем примере ввода только две пары. Каково определение пары?

3. @AdamMillerchip — я вижу три пары: (10, 10), (10, 10), и (20, 20).

4. @AdamMillerchip размер списка

5. @Todd зависит от определения пары, поэтому я и спросил. Но поскольку OP понравился ваш ответ, я думаю, вы правы.

Ответ №1:

Я смог сделать это, сгруппировав числа вместе, взяв результирующие списки и суммируя, сколько пар содержит каждый:

 fun sockMerchant(n: Int, pile: Array<Int>): Int =
    pile.groupBy { it }.values.sumBy { it.size / 2 }
  

После того, как мы это сделаем pile.groupBy { it } , у нас будет такая структура:

 {10=[10, 10, 10, 10], 20=[20, 20, 20], 30=[30], 50=[50]}
  

Мы берем значения и суммируем каждый их размер, деля на 2. При этом полупары будут округлены до 0, а полные пары — до 1 каждая.

Примечание: я не совсем понимаю, какова цель n в этом случае.

Ответ №2:

Я немного изменил его, чтобы его было легче тестировать, но вот исправления :

 import java.util.*

fun sockMerchant(n: Int, pile: Array<Int>): Int{
    var count = 0
    mutableMapOf<Int, Int>().withDefault { 0 }.apply {
        // the [attempted] logic behind this piece of code here is
        // that as we iterate through the list, the 'getOrPut()'
        // function will return either the value for the given [key]
        // or throw an exception if there is no such key
        // in the map. However, since our map was created by
        // [withDefault], the function resorts to its `defaultValue` <-> 0
        // instead of throwing an exception.
        for (e in pile) {
            // this simplifies our code and inserts a zero [ 1] where needed.
            // if (key exists)
            //      // return its associated value and MOD it:
            //      case: even  -> increment counter
            //            else  -> do nothing
            // else if (key dne)
            //      // insert default value <-> [0]   1
            //              ....
            //              ....
            //              ....
            println(e)
            put(e, getValue(e)   1)
            if (getValue(e) % 2 == 0) count  
            println(entries)
        }
    }
    return count
}


val n = 5
val ar = "10 10 10 10 20 20 30 40".split(" ").map{ it.trim().toInt() }.toTypedArray()
val result = sockMerchant(n, ar)
println(result)
  

Вывод :

 10
[10=1]
10
[10=2]
10
[10=3]
10
[10=4]
20
[10=4, 20=1]
20
[10=4, 20=2]
30
[10=4, 20=2, 30=1]
40
[10=4, 20=2, 30=1, 40=1]
3
Pair.kts:3:18: warning: parameter 'n' is never used
fun sockMerchant(n: Int, pile: Array<Int>): Int{
                 ^

Process finished with exit code 0
  

Объяснение :

  • Вы перебрали «значения», которые в начале пусты, поэтому вы ничего не делали со своим кодом
  • Даже при повторном цикле pile ваша логика увеличения не превышала 1, поэтому условие никогда не выполнялось, и количество никогда не увеличивалось.

Но основная аргументация была правильной.