# Multi-dimensional arrays exercise: Introduce married couples to each other

Following idea: There are three married couples and they have to be introduced another.

I have implemented this solution:

val couples = arrayOf(
arrayOf("Michael", "Sandy"),
arrayOf("Frank", "Claudia"),
arrayOf("Andrew", "Michelle")
)

for (i in 0 until couples.size) {
for (j in 0 until couples[0].size) {
var currentPerson = couples[i][j]

for (k in i + 1 until couples.size) {
for (l in 0 until couples[0].size) {
println("$currentPerson, this is${couples[k][l]}.")
}
}
}
}


Results in:

Michael, this is Frank.
Michael, this is Claudia.
Michael, this is Andrew.
Michael, this is Michelle.
Sandy, this is Frank.
Sandy, this is Claudia.
Sandy, this is Andrew.
Sandy, this is Michelle.
Frank, this is Andrew.
Frank, this is Michelle.
Claudia, this is Andrew.
Claudia, this is Michelle.


So I guess it's formally correct. But using that many loops isn't great.

Is there a way to reduce the amount of loops? Or is there a completely different approach to solve the problem?

• The data structures you've used seem a bit odd. Unless the names or couples will change at some point, it'd probably be best to use listOf to hold the list of couples, and to use a Pair for each couple. In case some of the couples get divorced, die, or become polygamous, you could perhaps use mutable lists for both the outer and inner lists. I also don't see a need to assign to currentPerson (and it can be a val instead of a var anyway).
– user
Jul 10 at 20:00
• It appears that each couple only has two people (since couples only consist of two people), so you can drop the second and fourth loops and just use 0 and 1 directly, unless you are planning for single people or more than two people as I've suggested above. I don't think you can do much else regarding the loops - the time complexity of this is going to be pretty high, but as long as you don't have too many couples to introduce to each other, it's probably fine.
– user
Jul 10 at 20:09
• @user I wish I could flag your comments with "Not a comment, it's an answer". I think you should post these things in an answer :) Jul 10 at 20:26
• @SimonForsberg I'll do so next time :)
– user
Jul 10 at 23:55

Efficiency-wise, I don't think you can do any improvements. At least none that I can think of. The four loops will have to be there in some way or another, but can of course be abstracted behind functions so that it doesn't give you so many levels of nesting.

Things that can be improved however, is typing and extensibility.

Algorithmitically speaking, your code is a more specific version of "There are X groups containing varying amount of people and they have to be introduced to another."

data class PeopleGroup(val people: Collection<String>)

Order doesn't really matter so I'm not specifying whether it's a List, or a Set, we could even generalize it to Iterable<String> but that's a bit overkill.

val groups: MutableSet<PeopleGroup> = mutableSetOf(
PeopleGroup(listOf("Michael", "Sandy")),
PeopleGroup(listOf("Frank", "Claudia")),
PeopleGroup(listOf("Andrew", "Michelle"))
)


That gives us some better structure. Note: I made it mutable so that we can remove already visited groups.

Now, to remove visited groups we can use an Iterator. And to handle the people to introduce a person to, we can use flatMap.

val iterator = groups.iterator()
while (iterator.hasNext()) {
val group = iterator.next()
iterator.remove()

for (person in group.people) {
for (other in groups.flatMap { it.people }) {
println("$person, this is$other.")
}
}
}


There are still some ways to improve this code, but I will leave you with this for now.

• You can directly use mutableSetOf to avoid the extra toMutableSet() (I don't know if that's idiomatic or if it has disadvantages, though).
– user
Jul 10 at 23:54
• @user Good point, fixed Jul 11 at 9:30