in benchmarks/src/jmh/kotlin/benchmarks/flow/scrabble/FlowPlaysScrabbleOpt.kt [20:111]
public override fun play(): List<Map.Entry<Int, List<String>>> {
val histoOfLetters = { word: String ->
flow {
emit(word.asFlow().fold(HashMap<Int, MutableLong>()) { accumulator, value ->
var newValue: MutableLong? = accumulator[value]
if (newValue == null) {
newValue = MutableLong()
accumulator[value] = newValue
}
newValue.incAndSet()
accumulator
})
}
}
val blank = { entry: Map.Entry<Int, MutableLong> ->
max(0L, entry.value.get() - scrabbleAvailableLetters[entry.key - 'a'.toInt()])
}
val nBlanks = { word: String ->
flow {
emit(histoOfLetters(word)
.flatMapConcatIterable { it.entries }
.map({ blank(it) })
.sum()
)
}
}
val checkBlanks = { word: String ->
nBlanks(word).map { it <= 2L }
}
val letterScore = { entry: Map.Entry<Int, MutableLong> ->
letterScores[entry.key - 'a'.toInt()] * Integer.min(
entry.value.get().toInt(),
scrabbleAvailableLetters[entry.key - 'a'.toInt()]
)
}
val score2 = { word: String ->
flow {
emit(histoOfLetters(word)
.flatMapConcatIterable { it.entries }
.map { letterScore(it) }
.sum())
}
}
val first3 = { word: String -> word.asFlow(endIndex = 3) }
val last3 = { word: String -> word.asFlow(startIndex = 3) }
val toBeMaxed = { word: String -> concat(first3(word), last3(word)) }
val bonusForDoubleLetter = { word: String ->
flow {
emit(toBeMaxed(word)
.map { letterScores[it.toInt() - 'a'.toInt()] }
.max())
}
}
val score3 = { word: String ->
flow {
val sum = score2(word).single() + bonusForDoubleLetter(word).single()
emit(sum * 2 + if (word.length == 7) 50 else 0)
}
}
val buildHistoOnScore: (((String) -> Flow<Int>) -> Flow<TreeMap<Int, List<String>>>) = { score ->
flow {
emit(shakespeareWords.asFlow()
.filter({ scrabbleWords.contains(it) && checkBlanks(it).single() })
.fold(TreeMap<Int, List<String>>(Collections.reverseOrder())) { acc, value ->
val key = score(value).single()
var list = acc[key] as MutableList<String>?
if (list == null) {
list = ArrayList()
acc[key] = list
}
list.add(value)
acc
})
}
}
return runBlocking {
buildHistoOnScore(score3)
.flatMapConcatIterable { it.entries }
.take(3)
.toList()
}
}