2
\$\begingroup\$

Problem statement for better understanding: Let's say we assign a unique number to each alphabet,

a=1, b=2, c=3...z=26

then find the frequency of the sum of each word for all possible three letter words (with or without meaning). E.g.

abc has sum of 6, yzx has a sum of 75, zzz has the sum of 78, cat has a sum of 24

and so on.

Following is my code in Kotlin.

    var h = mutableMapOf<Int, Int>()
    for(i in 1..26){
        for(j in 1..26){
            for(k in 1..26){
                val t = i+j+k
                if(h.containsKey(t)){
                    val count = h.get(t)
                    h[t] = count!!.plus(1)
                } else {
                    h.put(t, 1)
                }
            }
        }
    }
    println(h)

The output is:

{3=1, 4=3, 5=6, 6=10, 7=15, 8=21, 9=28, 10=36, 11=45, 12=55, 13=66, 14=78, 15=91, 16=105, 17=120, 18=136, 19=153, 20=171, 21=190, 22=210, 23=231, 24=253, 25=276, 26=300, 27=325, 28=351, 29=375, 30=397, 31=417, 32=435, 33=451, 34=465, 35=477, 36=487, 37=495, 38=501, 39=505, 40=507, 41=507, 42=505, 43=501, 44=495, 45=487, 46=477, 47=465, 48=451, 49=435, 50=417, 51=397, 52=375, 53=351, 54=325, 55=300, 56=276, 57=253, 58=231, 59=210, 60=190, 61=171, 62=153, 63=136, 64=120, 65=105, 66=91, 67=78, 68=66, 69=55, 70=45, 71=36, 72=28, 73=21, 74=15, 75=10, 76=6, 77=3, 78=1}

Regardless of the efficiency of the algorithm, how can I use functional programming in Kotlin to unwrangle the ugly loops to make it more readable and pleasant to the eyes?

  • EDIT: The solution need not be strictly in Kotlin
\$\endgroup\$
3
\$\begingroup\$

There are three things you are doing here:

  • Three loops
  • Sum
  • Grouping and counting

The way I would recommend to do these things in Kotlin are:

One loop: val loop = 1..26

Three loops and sum: loop.flatMap {x -> loop.flatMap { y -> loop.map { z -> x + y + z } } }

Grouping by and counting: .groupingBy { it }.eachCount()

Resulting code:

val loop = 1..26
val result = loop.flatMap { x -> 
    loop.flatMap { y -> 
        loop.map { z -> x + y + z }
    }
}.groupingBy { it }.eachCount()

Still though, I have to tell you that this is not an effective way and you might want to learn more about combinatorics in order to make a more efficient solution.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for your response. I will try this out and revert. \$\endgroup\$
    – Sid
    Jun 6 at 10:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.