Bramble
Bramble

Reputation: 1395

Count positive elements in list

Im trying count the number of positive elements in a list. Here is what I have so far:

 (define howMany
   (lambda (list)
      (cond
         [(not (list? list)) 0]
         [(null? list) 0]
         [(> list 0) (+ 1 (howMany (cdr list)))])))

It keeps giving me an error, "expects type real number", how would you fix this?

Oh im calling this like so:

(howMany '(6 7 8))

Upvotes: 1

Views: 1970

Answers (4)

Vijay Mathew
Vijay Mathew

Reputation: 27184

There are a couple of bugs in your code.

(> list 0) should be (> (car list) 0) as you want to check if the first element of the list is greater than 0. You cannot apply the default implementation of > to a list either.

(+ 1 (howMany (cdr list))) will also fail as howMany does not always evaluate to a number. You have to maintain a counter by passing that as an argument to the recursively called procedure. One way to do this is:

(define (howmany lst)
  (let loop ((n 0) (lst lst))
    (if (null? lst) n
      (loop (if (> (car lst) 0) (add1 n) n) (cdr lst)))))

Test:

> (howmany '(1 2 3 4 5))
5
> (howmany '(1 2 3 -4 5))
4
> (howmany '(1 -2 3 -4 5))
3
> (howmany '(-1 -2 3 -4 5))
2

Upvotes: 0

Paul Nathan
Paul Nathan

Reputation: 40309

positiveCounter(seq)
  if typeof(first(seq)) == num
      if first(seq) > 0
          return positiveCounter(rest(seq) + 1
      else
          return positiveCounter(rest(seq)
  else
      #Handle Errors Somehow. 

Pseudocode for the recursive algorithm I would use.

I don't know either Scheme or Clojure (which your square brackets remind me of).

Or you could write a considerably snazzier applicative approach in Common Lisp- extra newlines for readability.

(defun positiveCounter (seq)
  (reduce #'+
          (mapcar
           #'(lambda (x)
               (if (atom x)
                   (if (> x 0) 1 0)
                   0))
           seq)))

Upvotes: 0

Mihai
Mihai

Reputation: 2865

Here's your problem: (> list 0)

You're comparing a list to a number. Try (> (length list) 0) or (not (null? list)). Or whatever the Scheme keyword for "default condition in a cond block" is.

Edit: This is what you get when you focus on error messages foremost. Gareth has it right, of course.

Upvotes: 0

Gareth Rees
Gareth Rees

Reputation: 65854

You can't expect (> list 0) to work — list is a list, but > expects its arguments to be numbers.

You want to see if the first element of the list is positive, so that should be (> (car list) 0).

However: there's a bigger problem with your code: what happens if the first element is negative or zero?

Upvotes: 4

Related Questions