Search code examples
vectorschemeracketminimum

Find second smallest value of a vector


I have construced a procedure which should take an argument, a vector with numbers as entries, and then return the lowest value.

(define min-number
  (lambda (vec)
    (define looping
      (lambda (i v-min)
        (if (= i (vector-length vec))
            v-min
            (looping (+ i 1) (min v-min (vector-ref vec i))))))
    (looping 1 (vector-ref vec 0))

    )
  )

Now I want to construct a procedure which returns the second smallest value of a vector. This is something which should be done without converting the vector to a list. Any ideas of how I could do so? I can't get my head out of the "list-thinking". My head says to me "use car", "use cdr" and so on which doesn't work in this particular case. So any ideas would be greatly appreciated. Hmm, I think I covered everything, if something is unclear, let me know.

Thanks :)


Solution

  • If you're allowed to use built-in functions, here's an easy way: find the minimum value, and then look for the next minimum value which is not that minimum. This is what I mean:

    (define min-number
      (lambda (vec)
        (let ((min-val (vector-argmin identity vec)))
          (vector-argmin
           (lambda (x) (if (equal? x min-val) +inf.0 x))
           vec))))
    

    For example:

    (min-number '#(5 4 1 2 3))
    => 2