Kotlin Filtering a list of Objects to make sure at least 1 Workstation is covered

Viewed 32

In Kotlin I need to make sure all workstations are covered, so people can book time off, there are 4 workstations but people can only do 1 at a time. I need to ensure all Workstations have at least 1 person in to cover it, the issue I have with my code is that people are capable of multiple workstations

enum class WorkStations {
    PANEL, OUTSIDE, MOVEMENTS, EXTRUDER
}

data class Operator(val name: String, val workStations: List<WorkStations> = 
emptyList())

fun main() {

val array = arrayListOf(
    Operator(
        "Andy",
        listOf(WorkStations.PANEL, WorkStations.OUTSIDE, WorkStations.MOVEMENTS)
    ),
    Operator(
        "Alan",
        listOf(WorkStations.PANEL, WorkStations.OUTSIDE, WorkStations.MOVEMENTS)
    ),
    Operator(
        "Matt",
        listOf(WorkStations.OUTSIDE)
    ),
    Operator(
        "Paul",
        listOf(WorkStations.EXTRUDER, WorkStations.MOVEMENTS)
    ),
    Operator(
        "Jack",
        listOf(WorkStations.EXTRUDER, WorkStations.MOVEMENTS)
    ),
    Operator(
        "James",
        listOf(WorkStations.OUTSIDE)
    ),
    Operator(
        "Tall Paul",
    ),
    Operator(
        "Josh")
    )

fun areWorkStationsCovered(array: ArrayList<Operator>): Boolean {
    val newList = array.flatMap { it.workStations }.groupingBy { it }.eachCount().filter { it.value >= 1 }
    println(newList)
    return newList.size >= 4
}

println(areWorkStationsCovered(array))

}

returns:

{PANEL=2, OUTSIDE=4, MOVEMENTS=4, EXTRUDER=2}
true

But this isn't correct, as if Paul and Alan are off then this is returned:

{PANEL=1, OUTSIDE=3, MOVEMENTS=2, EXTRUDER=1}
true

It looks ok but its not correct as Jack would need to do the EXTRUDER therefore only 1 movements person and Andy would have to do the PANEL therefore no Movements person, I think I need to remove people from the original list but just cant think of a simplistic, functional approach any thoughts would be greatly appreciated...

1 Answers

If I understand the problem correctly, each operator may perform only one workstation and each workstation must be occupied at least once.

Surely there is a better and more performant solution. But you can always optimize in the end.

This should work:

Display all operators, which can cover 1 workstation. For example James. James must take over Outside. You add this to a new list coveredWorkStations.

Afterwards you give all operators, which can cover 2 workstations and all operators, which can cover 1 workstation, which is NOT stored in coveredWorkStations.

There you get for example Jack and Paul. Jack and Paul may now no longer cover workstations that are already in coveredWorkStations. Take for example Jack, which is Extruder.

Then you search for all operators which can cover three workstations and all operators that can cover workstations that are NOT yet in coveredWorkStations. Do this until you have gone through all operators with the workstations.

Related