@user424683: Hey mate, i'm stuck on this question as well. Are you my class?
Please guys help us!
here's the whole question:
Consider the problem of processing examination marks to produce a final classlist. There are two inputs to the problem, both of them non-empty lists. One list, known only to the examiner, consists of an alphabetically ordered list of candidate names together with candidate id numbers. For example:
ANDERSON 101372
BAYLIS 101369
CARTER 101370
DENNIS 101371
EDWARDS 101373
The second list, produced by the marker for the examination, consists of
an ordered list of candidate id numbers and the marks. For example:
101369 62
101370 75
101371 62
101372 30
101373 50
The task of the examiner is to use these two lists to produce a class list in
alphabetical order of candidate names, their marks, and their final ranking. A
candidate has rank n if and only if there are exactly (n-1) candidates with higher
marks. It is also required to print the result in a suitably readable format. For
example:
ANDERSON 30 5
BAYLIS 62 2
CARTER 75 1
DENNIS 62 2
EDWARDS 50 4
We introduce some appropriate types:
type Name = String
type Iden = Integer
type Mark = Int
type Rank = Int
type Codes = [(Name, Iden)]
type Marks = [(Iden, Mark)]
type Ranks = [(Name, Mark, Rank)]
(a) Your main task in this question is to define the function
classlist :: (Codes, Marks) -> Ranks
that takes the list of names and id numbers, and the list of id numbers and
marks, and returns the list of names, marks, and final rankings.
This function can be constructed as a composition of two phases: 1. collating
marks with candidate names, and 2. producing the ranking.
To collate names with marks, we can assume that the list of codes is ordered
alphabetically by Name, the list of marks is ordered numerically by Iden,
that no two candidates have the same name or id number, and that the two
lists have equal length.
To compute the rank for each candidate we need to count the number of
candidates with higher marks. The problem of computing rank can be made
much easier by sorting the list in descending order of marks. If a candidate
has the same mark as the immediately preceding candidate, they both get the
same rank.
You should make use of higher-order functions where possible, in order to
simplify your solution (eg. map, filter, zip, zipWith.) You should also
make use of the following functions:
1. sortby :: Ord b => (a -> b) -> [a] -> [a]
sortby is a higher-order function that takes a function with an ordered
result type as its first argument. The specification of sortby f xs is that
it sorts the items in the list xs using the values that are generated by applying
the function f to each item in the list.
sortby f xs returns a permutation ys of xs satisfying (f x <= f y)
for each pair of list elements (x,y) where x is the predecessor of y in
ys.
Consider, for example, sortby markfn classmarks where
markfn :: (Name, Mark) -> Mark
such an instance of sortby could be used to sort a list of (Name, Mark)
pairs by mark.
2. sortwith :: (a -> a -> Bool) -> [a] -> [a]
sortby is a higher-order function that takes a binary function which returns
a Boolean value as its first argument. The specification of sortwith f xs
is that it sorts the items in the list xs using the function f to compare pairs of
items in the list.
sortwith f xs returns a permutation ys of xs such that f x y
evaluates to True for each pair of list elements (x,y) where x is the
predecessor of y in ys.
Consider, for example, sortwith compmks classmarks where
compmks :: (Name, Mark) -> (Name, Mark) -> Boolean
such an instance of sortwith could be used to sort a list of (Name, Mark)
pairs by mark, in either ascending or descending order, depending on how
compmks was defined.
Thanks so much for any helps!