//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Determine how many monos we can fit in a number of rooms. </summary> /// /// <remarks> /// This returns a list of room assignments. Each room assignment is a list with one element for /// each room. Each of those elements is a list of the monopoles that can be placed in that /// room. Darrell Plank, 6/10/2020. /// </remarks> /// /// <param name="cRooms"> The count of rooms. </param> /// /// <returns> A List of an array of lists. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// private List <List <int>[]> MonosInRooms(int cRooms) { var ra = new RoomAssignments(cRooms); var(assignments, _) = TryPlace(1, 0, ra, 1); return(assignments); }
private static (List <List <int>[]> assignments, int maxMono) TryPlace(int monopole, int room, RoomAssignments ra, int minMonos) { if (!ra.Place(monopole, room)) { return(new List <List <int>[]>() { ra.CloneAssignments() }, ra.NextUnassigned - 1); } var ret = new List <List <int>[]>(); // Good - we were able to place mono in requested room. Go on and try to place the next monopole // in each valid room. var nextMono = ra.NextUnassigned; var fPlacedInEmptyRoom = false; for (var iRoom = 0; iRoom < ra.RoomCount; iRoom++) { var isEmptyRoom = ra.MonosInRoom(iRoom).Count == 0; if (fPlacedInEmptyRoom && isEmptyRoom) { // No sense in trying to place the monopole in two separate empty rooms continue; } fPlacedInEmptyRoom = fPlacedInEmptyRoom || isEmptyRoom; var(assignments, count) = TryPlace(nextMono, iRoom, ra, minMonos); if (count > minMonos) { ret = assignments; minMonos = count; } else if (count == minMonos && count >= nextMono) { ret.AddRange(assignments); } // Only remove if we successfully placed if (count >= nextMono) { ra.Unplace(nextMono, iRoom); } } return(ret, minMonos); }