Nikolai Naidenov
Nikolai Naidenov

Reputation: 37

Minimum between a list and a number

I'm having some complications with a piece of code I'm working on. I need the procedure to take number (list-of-numbers) and return the minimum value between the two. So far I have this

(define (mini y lon)
 (cond
  [(empty? lon) y]
  [else (min (first (foldr cons lon (list y))) (mini y (rest lon)))]))

and I can't figure out the reason why it's not working. Thanks in advance.

Upvotes: 0

Views: 630

Answers (2)

Sylwester
Sylwester

Reputation: 48745

I think Óscar nailed it for a racket solution, but since you tagged the cmpletely different languages Scheme and Lisp I made som solutions to fit those tags as well.

A R6RS-solution using the native fold-left from (rnrs lists)

#!r6rs ; #!r7rs
(import (rnrs base) (rnrs lists)) ; (import (scheme base))

(define (mini x xs)
  (fold-left min x xs))

;; without fold
(define (mini-simple x xs)
  (apply min x xs))

Since you tagged lisp, here is a Common Lisp version. CL doesn't have foldl/foldr, but reduce which replaces both and more:

(defun mini (x xs)
  (reduce #'min xs :initial-value x))

Upvotes: 3

Óscar López
Óscar López

Reputation: 235994

The solution is overly complicated, why using foldr and min, when a simple min together with apply will do all the work? try this:

(define (mini y lon)
  (apply min y lon))

... Or you can build a single list with y and lon, but once again you don't need foldr for this, a simple cons is all you want:

(define (mini y lon)
  (apply min (cons y lon)))

... But if you really, really need to use foldl (or foldr), then it's not required to use min, the trick is to pass the right function:

(define (mini y lon)
  (foldl (lambda (e a) (if (< e a) e a)) ; foldr will also work
         y
         lon))

... Or you could use min after all, for a shorter solution. There are so many ways to solve this problem!

(define (mini y lon)
  (foldl min y lon)) ; foldr will also work

Upvotes: 3

Related Questions