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\$

1 Answer 1

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\$ Commented Jun 6, 2021 at 10:39

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.