title: How to design an algorithm to put elements into groups with constraints?
body: <p>I was given a task of putting students into groups (to prepare a coding camp), but with several constraints. Though I've finished the task by hand, I'd like to know is there already exist some algorithms for tasks like this, or how can I design such an algorithm.</p>
  
  <hr>
  
  <p><strong>Background</strong>: 40 students in total, with these attributes:</p>
  
  <ul>
  <li>gender: F/M</li>
  <li>grade: Year 1/2</li>
  <li>school: School 1/School 2/...</li>
  <li>early assessment result: Rank from 1 to 40</li>
  </ul>
  
  <p><strong>Constraints</strong>: All of them needs to be satisfied.</p>
  
  <ol>
  <li>Exactly 4 people per group</li>
  <li>Each group needs to have at least a girl</li>
  <li>Each group needs to have at least a Year 2 student</li>
  <li>4 group members needs to come from 4 different schools</li>
  <li>Each group needs to have at least a student who ranked top 10 in early assessment</li>
  </ol>
  
  <p><strong>What I'm expecting</strong>:</p>
  
  <ul>
  <li>The Best: An existing algorithm/program for these kind of problems</li>
  <li>Or, An algorithm for this specific problem</li>
  <li>Or at least, Some ideas of creating an algorithm for this specific problem</li>
  </ul>
  
  <hr>
  
  <p><strong>My thoughts</strong>:
  Since I've successed in making groups by hand, I know that such a solution indeed exists for my current dataset. But if I need an algorithm to find a solution for me, it should first try to check whether a solution even exists, by check if the number of girl / Year 2 students is greater than 10 (with pigeonhole principle), and some other conditions. And obviously, Constraint 5 is the easiest, and can provide a base solution for the rest. However, I still can not find a systematic way of doing it. Perhaps bruteforce and randomization can help? I'm not sure.</p>
  
  <p>And sorry, since the data is confidential, I can not post it.</p>
  
  <hr>
  
  <p><strong>Update</strong>: After consulting a friend, here is a possible method:</p>
  
  <ol>
  <li>First put the top 1 to 10 into 10 different groups.</li>
  <li>Then iterate through groups. If the only person in the group is a boy/girl, try to add a girl/boy from a different school.</li>
  <li>Then the problem size is reduced from 2^40 to 2^20, making bruthforce a viable solution.</li>
  </ol>