Search code examples
schemeracketimperative

How do I scale values all the values in a list where the largest value is 1 and the smallest value is 0


I am trying to scale all the values in a list where the largest value is 1 and the smallest value is 0. Here is an example of what I am trying to accomplish

(check-expect (squash (list 100 90 70 20)) (list 1 0.875 0.625 0)).

As you can see the largest value is 100 so it's scaled value is 1, the smallest value which is 20 is scaled down to 0.

To scale all these values down i'm performing the calculation Z=(Li - (smallest-val)) / ((largest-val) - (smallest-val))

where Li is all the values in the list (L1, L2, L3 ...)

Here is my code so far

(define (squash L)
  (local
    [
     ;;(largest-val M) returns the largest value M in L
     ;;(largest-val: (listof Num) -> Num
     (define (largest-val M) (foldr max (first M) (rest M)))

     ;;(smallest-val x) returns the smallest value x in L
     ;;(smallest-val: (listof Num) -> Num
     (define (smallest-val x) (foldr min (first x) (rest x)))
     ]
    (cond
      [(empty? L)'()]
      [else (cons (/ (- (first L) smallest-val) (- largest-val smallest-val))
                   (squash (rest L)))])))

Here is my error I am getting

:: -: expects a number as 2nd argument, given (lambda (a1) ...)

I'm unsure how to fix this code so my program works

I want to keep my solution using the imperative programming paradigm so I would prefer to keep my answer in the same format as it is now.


Solution

  • Here is a variation of your function:

    (define (squash L)
      (local
        [
         ;;(largest-val M) returns the largest value M in L
         ;;(largest-val: (listof Num) -> Num
         (define (largest-val M) (foldr max (first M) (rest M)))
    
         ;;(smallest-val x) returns the smallest value x in L
         ;;(smallest-val: (listof Num) -> Num
         (define (smallest-val x) (foldr min (first x) (rest x)))
         (define (scale x)
           (/ (- x                 (smallest-val L))
              (- (largest-val  L)  (smallest-val L))))]
        (map scale L)))
    

    The function map applies the function scale to each element of the list L and returns a new list with all the results.