Tavern Challenge

I don’t really understand how use a sequence to generate all the unique names.

From what I understand, a sequence doesn’t produce any values until it is asked to. Am I correct in thinking that in the code provided for generating a random set of names using the sequence, nothing will be generated until toSet() is called? If that is the case, how are you supposed to check the current name being generated to the previously generated names? When I look back at the prime number example, I don’t see how to apply that to the challenge. I understand how the filter function works in that context as it doesn’t have to check against any of the previously generated values.

Thanks!

Hi zvg, thanks for the question!

The solution to the challenge using sequences here required just a bit of a stretch.
Check out the following code - which applies the distinct function to the sequence, just before the take function:

val one = listOf("larry", "moe", "curly")
val two = listOf("boggs", "scaggs", "simpson")

fun main(args: Array<String>) {
    val patrons = generateSequence {
        one.shuffled().first() + two.shuffled().first()
    }.distinct()
      .take(9)
      .toSet()
    println(patrons.size)
}

Notice that the number 9, the max unique value for combining these two lists, is always printed.
This may behave a bit differently than what you’d expect since you might think distinct would apply to only a single element, but if you dig into the implementation of distinct you will see that it actually applies to all elements (take a look at the DistinctIterator class’s computeNext function to see how it works).
The result is that when distinct and take are called on the sequence, all values from the sequence will be unique ones.

Hope that helps! Thanks again for the question.

4 Likes

Why use .toSet (), if we use distinct(). Is it possible to bypass distinct() with a filter() or by other methods?