internal static class Program
private struct CrewMember
public CrewMember Member;
private interface IMissionRequirement
bool Validate(CrewClone[] clones);
private abstract class MissionRequirement : IMissionRequirement
protected MissionRequirement() { }
public abstract bool Validate(CrewClone[] clones);
private sealed class MinimumLevelSumRequirement : MissionRequirement
public int MininumLevelSum
public MinimumLevelSumRequirement(int minimumLevelSum)
throw new ArgumentOutOfRangeException(nameof(minimumLevelSum), minimumLevelSum, "The value must be greater than or equal to zero.");
this.MininumLevelSum = minimumLevelSum;
public override bool Validate(CrewClone[] clones)
for (int i = 0; i < clones.Length; ++i)
currentSum += clones[i].Level;
if (currentSum >= this.MininumLevelSum)
private sealed class MinimumCrewQuantityRequirement : MissionRequirement
public int MininumCrewQuantity
public MinimumCrewQuantityRequirement(int minimumCrewQuantity)
if (minimumCrewQuantity < 0)
throw new ArgumentOutOfRangeException(nameof(minimumCrewQuantity), minimumCrewQuantity, "The value must be greater than or equal to zero.");
this.MininumCrewQuantity = minimumCrewQuantity;
public override bool Validate(CrewClone[] clones)
return clones.Length >= this.MininumCrewQuantity;
private sealed class MaximumCrewQuantityRequirement : MissionRequirement
public int MaximumCrewQuantity
public MaximumCrewQuantityRequirement(int maximumCrewQuantity)
if (maximumCrewQuantity < 0)
throw new ArgumentOutOfRangeException(nameof(maximumCrewQuantity), maximumCrewQuantity, "The value must be greater than or equal to zero.");
this.MaximumCrewQuantity = maximumCrewQuantity;
public override bool Validate(CrewClone[] clones)
return clones.Length <= this.MaximumCrewQuantity;
private sealed class MinimumCrewRoleQuantityRequirement : MissionRequirement
public int MinimumQuantity
public MinimumCrewRoleQuantityRequirement(CrewRole role, int minimumCrewQuantity)
if (minimumCrewQuantity < 0)
throw new ArgumentOutOfRangeException(nameof(minimumCrewQuantity), minimumCrewQuantity, "The value must be greater than or equal to zero.");
this.MinimumQuantity = minimumCrewQuantity;
public override bool Validate(CrewClone[] clones)
for (int i = 0; i < clones.Length; ++i)
if (this.Role == clones[i].Member.Role)
if (++currentQuantity >= this.MinimumQuantity)
private sealed class Mission
private readonly MissionRequirement[] requirements;
public Mission(string name, MissionRequirement[] requirements)
throw new ArgumentNullException(nameof(name));
if (requirements is null)
throw new ArgumentNullException(nameof(requirements));
this.requirements = requirements;
public bool IsCrewValid(CrewClone[] crewClones)
throw new ArgumentNullException(nameof(crewClones));
for (int i = 0; i < this.requirements.Length; ++i)
if (!this.requirements[i].Validate(crewClones))
public int[] GetValidCrewIndices(CrewClone[] crewClones)
throw new NotImplementedException();
private static void Main()
CrewMember[] members = new CrewMember[]
new CrewMember() { Name = "Alan", Role = CrewRole.Engineer },
new CrewMember() { Name = "Nancy", Role = CrewRole.Engineer },
new CrewMember() { Name = "Margaret", Role = CrewRole.Tactical },
new CrewMember() { Name = "Frederick", Role = CrewRole.Tactical },
new CrewMember() { Name = "Charlie", Role = CrewRole.Science },
new CrewMember() { Name = "Lewis", Role = CrewRole.Science },
new CrewMember() { Name = "John", Role = CrewRole.Civilian },
new CrewMember() { Name = "Karen", Role = CrewRole.Civilian },
new CrewMember() { Name = "Shirley", Role = CrewRole.Commander },
new CrewMember() { Name = "Etienne", Role = CrewRole.Commander },
new CrewMember() { Name = "Chris", Role = CrewRole.Medical },
new CrewMember() { Name = "James", Role = CrewRole.Medical }
CrewClone[] availableClones = new CrewClone[]
new CrewClone() { Member = members[0], Level = 1 },
new CrewClone() { Member = members[2], Level = 1 },
new CrewClone() { Member = members[4], Level = 1 },
new CrewClone() { Member = members[6], Level = 1 },
new CrewClone() { Member = members[8], Level = 1 },
MissionRequirement[] requirements = new MissionRequirement[]
new MinimumLevelSumRequirement(4),
new MinimumCrewQuantityRequirement(2),
new MaximumCrewQuantityRequirement(4),
new MinimumCrewRoleQuantityRequirement(CrewRole.Commander, 1),
new MinimumCrewRoleQuantityRequirement(CrewRole.Engineer, 1)
Mission mission = new Mission("The first mission", requirements);
int[] crewIndices = mission.GetValidCrewIndices(availableClones);
CrewClone[] crewClones = new CrewClone[crewIndices.Length];
for (int i = 0; i < crewClones.Length; ++i)
crewClones[i] = availableClones[crewIndices[i]];
if (mission.IsCrewValid(crewClones))
Console.WriteLine("Passed. Selected a valid crew.");
Console.WriteLine("Failed. Selected an invalid crew.");