Trying to create a list of unique numbers. Why is ...
# getting-started
a
Trying to create a list of unique numbers. Why is this statement not working?
Copy code
mineLocation = Set<Int>(mineCount) { Random.nextInt(0, length * width)}
p
Set is interface or you have own implementation for this class?
a
Well I was trying to create a unique list of random elements Trying to avoid:
Copy code
var mineLocations = arrayListOf<Int>()
while(mineCount != minesSet) {
    val i = Random.nextInt(0, length * width)
    if (!mineLocations.contains(i)) {
        mineLocations.add(i)
        minesSet++
    }
}
p
Anyway, I think Kotlin doesn’t have this functional, need to do own solution, e.g.
Copy code
val rands = mutableSetOf<Int>()
val mineCount = 10
        
while (rands.size != mineCount) {
  rands.add(Random.nextInt())
}
// return immutable set
rands.toSet()
In theory about data structures, Set must contains only unique elements, so calling contains method is unnecessary
a
This is for a minesweeper game. I think ideally a map should be used for each mine but I think I could get away with a set or list. What would be the better recommended approach?
p
Each point of mine has two states: mined or not?
m
Are you trying tro create a function that takes in the parameter
mineCount
? That's not obvious to me since that parameter is not used...and where is
length
and
width
stated? Also,
Set
is as pointed out before a data structure that only contains uniqiue elements. Moreover, it is by default unordered so there's no need of randomizing here
Also, I don't really understand why they have to be random here at all but I don't have the exact use case. Anyway, the code that you pasted above (with the array list etc) can be rewritten as
Copy code
val width = 10
val height = 10
val size = width * height //I mean, shouldn't this be a grid (2d-array or so), rather than the product of two numbers?

//This is really all you need. The randomization seems completely unnecessary to me, but maybe I don't understand the use case?
(0..size).toSet()
m
Alex, your initial code would be cool but sadly only List has a generator function (written to look like a constructor). You could define your own function anyway that encapsulates the creation code. Another take using sequences could be: Alex, your initial code would be cool but sadly only List has a generator function (written to look like a constructor). You could define your own function anyway that encapsulates the creation code. Another take using sequences could be:
Copy code
val mineLocation = generateSequence { Random.nextInt(0, length * width) }
        .distinct()
        .take(mineCount)
        .toSet()
m
Okay, NOW I understand...too early in the morning for me - didn't connect that we were trying to place out mines...sorry Alex... 😂
m
@mickeelm you didn’t get the use case: he’s trying to generate a random subset of locations on a grid. Your code generates a set of all the locations. 😛
m
Yeah, I'm sorry about that 😂
m
we wrote at the same time, sorry
😃 1
so you can encapsulate the above code inside this function to obtain your desired idiom:
Copy code
inline fun <T> Set(size: Int, init: () -> T): Set<T> = ...
a
I have not done inline functions like that yet, only lambda functions.
m
nothing fancy here, just copying the initial
List(Int, (Int) -> T))
definition from standard lib: this small optimization will let the compiler inline the
init
lambda when creating the Set and the Set function itself at the call site, to avoid creating a function object
if you’re not familiar with this feature, just ignore the
inline
modifier, don’t worry