AAU group formation ****

In this exercise we will work the concepts student, group and grouping. The overall purpose is to program various ways to make groups of students for AAU student project groups.

A student has the following properties: Student-id, name, sex, ethnicity (country born), and age. The student-id is unique, and it corresponds directly to the AAU student number (represented as a string). The sex is either "male" or "female" (both strings). The nationality is a string (such as "Danish"). The age is a non-negative integer. As such, a student can be represented by various list formats, or as a struct.

A group is is a set of students, which, for some purpose, belongs together (such as in a semester group at AAU). The group also has a group-id, which in this exercise is an integer group number (starting from 1). A group can be represented as group-id together with a list of students, or (shorter) together with a list of student-ids.

A grouping attaches a group to each student in our population of interest. Thus, in a grouping each student should belong to exactly one group. A grouping can be represented as a list of groups. Alternatively, a grouping can be represented as an association list which maps student-ids to group-ids. In this exercise, we recommend that grouping should is represented as an association list, which associcates a group number to a student. As an example, the association list (ordered arbitrarly):

((1 . a) (1 . e) (2 . b) (1 . c) (2 . d))

defines a grouping consting of two group. Group 1 consists of the students `a`, `e` and `c`. Group 2 consists of the students `b` and `d`.

Write a function that return a given group from a grouping. In additon, write a function that returns the number of groups in the grouping, a function that return the max group size in a grouping, and a function that returns the min group size in a grouping.

The starting point of this exercise is a population of n students. There exists a sample population of 200 students, which can be used as the starting point in solution to this exercise.

Write constructor, predidate, selection functions for a single student. As part of this you must decide how to represent a student in your program.

Write a constructor function for a single group, and write a group predicate function. In addition, write a selector function that returns a list of students in the group, and a selector function that returns the group-id (group number). (Both the constructor and selectors will most likely be trivial, but it is good for us to have these functions available).

The various grouping functions (discussed below) will serves grouping constructor functions. Write a predicate that identifies a grouping object.

For practical purposes it is recommended to program (pretty)printing functions for students, groups and groupings.

**Random grouping:**
Given a list of students *sl* and list desired group sizes *gsl*, program a grouping function that forms `(length gsl)` groups, of the sizes prescribed in gsl.
This grouping function should return a grouping.
The function should asserts that gsl is a list on positive integers (g1 g2 ... gk), where g1+g2+...+gk = (length sl).
The grouping should be recursive, in a straightforward way:
Initially, form a group of g1 students (randomly selected with use of your random function), and solve the remaining random grouping problem recursively, for the group size list (g2 ... gk).

**Grouping by counting:**
Program a second grouping function which mimics the "manual couting approach" to the formation of *k* groups.
In this approach, the grouping relies somehow on the order of students in the student collection.
The counting goes: 1, 2, ..., *k*, 1, 2, ... *k*, ... (a total of *n* times where *n* is the number of students).
This leads to a marking of each student by the allocated group number, and based on the marking, a grouping object should be created.

**Balanced grouping by counting:** As a variant of grouping by counting, program a third grouping function to form *k* groups from the *n* students which ensures equal distribution of sex and equal distribution of ethnicality in the constructed groups.
As equal as possible in the real world. Please come up with a good, pragmatic and reasonable solution.

**Random grouping with group predicate.**
As a variant of random grouping, add a group predicate to the parameter list of grouping function.
Do your best to form groups that fulfill the group predicate.
If a (random) group is formed, which breaks the group predicate, redo the random pick of the group (up to a limit, such as 1000 times).
Program and play with the following group predicates:

- At least N students in a group are A years old, or older.
- All students in the group are female.
- No students in the group are of the same age.

It is allowed to use a non-pure random function function for random grouping (such as `random` in Racket).
In addition, you are allowed to write non-pure print functions.
All other functions in your solution should be pure functions.

There is no solution to this exercise