Formulate the following problems in terms of a map(), a fold(), or a
combination of map() and fold(). You do not need to specify the full
definition of your map() or fold(); just give a few sentences on what
would be performed by each function.
1. Given a list of vectors [(x1, y1, z1), (x2, y2, z2), ... ], add
them to determine the resultant vector. Note that by "vector" we are
referring to a physics vector, e.g., a displacement vector.
fun AddVectors lst =
foldl (fn ((x,y,z),(a,b,c)) => (x+a, y+b, z+c)) (0,0,0) lst
2. Given a company's monthly paystubs for all employees for an entire
year, calculate how much income tax is owed per-person. Your input will
be an unordered list of the form [ (empID1, monthID1, monthlyWage1),
(empID1, monthID2, monthlyWage2), (empID5, monthID5, monthlyWage5), ... ],
and your output should be of the form [ (empID1, taxOwed1), ... ].
Fold over the input list to create a new list containing all
the employee ids along with the sum of their wages. This will
involve an inner map over the list being passed along as the
accumulator, which must find the employee id that is the same,
and update it with the monthly salary total. Then do a final
map to compute tax from wages
fun calculateTaxes lst =
let allIds = foldl (fn ((emp,_,_), ids) =>
if (List.exists (fn id => id = emp) ids)
then ids else emp::ids) lst in
let ids_with_zeros = map (fn x => (x,0)) allIds in
let ids_with_wages = foldl
((fn (emp,_,wage),ids) =>
map (fn (id,sum) => if id=emp
then (id,sum+wage) else (id,sum)) ids) ids_with_zeros lst
in
map computeTaxFromWages ids_with_wages
(List.exists f lst returns true if (f x) is true for some x in lst,
and false otherwise.)
3. Find the smallest element in an array.
fun ListMin lst =
foldl (fn (x,a) => if (x < a) then x else a) INT_MAX lst
4. Bonus question: Run-length encoding
Run-length encoding takes a possibly-repetitive string and rewrites
it as a (substring, frequency) pair, eg "aaabccccdd" becomes "a3bc5d2"
(an exercise for the adventurous.)