Search code examples
listdictionaryschememultiplication

(Scheme) Using custom map and reduce, find minimum value in a list


I need to use the 2 functions below to find out the minimum value in a list after squaring every element.

For example: (minSquare '(10 -2 5 9 -11) should print out 4.


map and reduce code:

(define map
  (lambda (f l)
    (if (null? l)
        '()
        (cons (f (car l)) (map f (cdr l))))))

(define reduce
  (lambda (op l id)
    (if (null? l)
        id
        (op (car l) (reduce op (cdr l) id)))))

I tried this:

(define minSquare
  (lambda (x)
    (cond [(null? x) '()]
          [else (map minSquare (reduce * x (car x))) (minSquare (cdr x))])))

But that passes all the numbers in the list multiplied by their squares to map then crashes giving a contract violation. I'm not sure how to use those two functions.

If someone can guide me through it (not give the answer), I would greatly appreciate it!

NOTE: I can't modify map or reduce.


Solution

  • First you have to map over the list squaring every element, and after that find the minimum using reduce. Some hints:

    • reduce receives three parameters, the first is a procedure that compares each element with an initial minimum, updating its value whenever we find an element that is less than the current minimum.
    • The second parameter is the list to traverse, which in this case is the result of squaring each of the elements: (map (lambda (n) (* n n)) x).
    • The third parameter is the initial minimum value, in this case is a number such that all the others will be less than it, for example the positive infinity +inf.0.

    Notice that using reduce here is a bit of an overkill, given that the language already provides us with a min function.