Question

I am trying to find the mode of a list

Assuming the list is sorted ascending order

Here is my mode function

 (define freq
   (lambda (l)
     (cond ((null? l)l)
           ((null? (cdr l))l)
           ((not(equal? (car l) (car(cdr l))))(freq(cdr(delete l (car l)))))
           (else (freq (cdr l)))
 )))

   (freq '(4 4 4 4 5 7 9 9 9)) => should returns 4 but its returning 9 instead
Was it helpful?

Solution

Here's my solution, which is similar to Óscar's solution but centralises the update of the longest/winning result in one place:

(define (longest-run lst)
  (let loop ((result #f)
             (cur #f)
             (count 0)
             (longest 0)
             (lst lst))
    (cond ((> count longest)
           (loop cur cur count count lst))
          ((null? lst) result)
          ((eqv? (car lst) cur)
           (loop result cur (+ count 1) longest (cdr lst)))
          (else
           (loop result (car lst) 1 longest (cdr lst))))))

I think my solution is shorter, cleaner, and less repetitive, but Óscar's solution has the advantage of updating the variables fewer times: his solution only updates the variables at the end of a run, whereas mine updates the variables whenever the current length is longer than the longest length seen so far.

OTHER TIPS

What's the logic behind your procedure? how do you expect it to find the mode by removing elements from the input list? you should be counting frequencies instead:

(define (mode lst)
  (if (null? lst)
      #f ; edge case: an empty list doesn't have a mode
      (let loop ((lst lst) ; list to traverse
                 (current (car lst)) ; current element in sequence
                 (counter 0) ; number of times current element appears
                 (max-current (car lst)) ; the mode
                 (max-counter 0)) ; number of times the mode appears
        (cond ((null? lst) ; the list is finished
               (if (> counter max-counter) current max-current))
              ((= (car lst) current) ; current element equal to previous
               (loop (cdr lst) ; add 1 to counter and keep iterating
                     current
                     (add1 counter)
                     max-current
                     max-counter))
              (else ; found a different element, a new sequence starts
               (loop (cdr lst)
                     (car lst) ; update current element
                     1
                     (if (> counter max-counter) current max-current)
                     (max counter max-counter)))))))

It works by keeping track of how many times each element appears, returning the element that appears most frequently - because by definition the mode is the value that appears most often in a set of data. We take advantage of the fact that the input list is sorted, because we know that a new sequence of repeated elements starts when the current element is different from the previous one we encountered.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top