kelly
kelly

Reputation: 413

Counting numbers or characters in list in Scheme

does anyone know how to count all numbers or characters in list and print it in pair in this format: (number . number_of_occurrences). For example:

(count '(3 1 3 2 1 2 3 3 3))

((3 . 5) (1 . 2) (2 . 2))

(count '(d b a c b b a))

((d . 1) (b . 3) (a . 2) (c . 1))

Thanks in advance for helping me :)

Upvotes: 1

Views: 2252

Answers (2)

Óscar López
Óscar López

Reputation: 236150

Here's an idea - use a hash table to keep track of the number of occurrences. This is an O(n) procedure:

(define (counter lst)
  (let ((counts (make-hash)))
    (let loop ((lst lst))
      (cond ((null? lst)
             (hash->list counts))
            (else
             (hash-update! counts (car lst) add1
                           (lambda () 0))
             (loop (cdr lst)))))))

Alternatively, here's a simpler version (it doesn't use filter) of @mobyte's solution in Scheme - noticing that this is O(n^2) and hence less efficient than the hash table-based procedure:

(define (counter lst)
  (map (lambda (e)
         (cons e (count (curry equal? e) lst)))
       (remove-duplicates lst)))

Either way, It works as expected:

(counter '(3 1 3 2 1 2 3 3 3))
=> '((3 . 5) (2 . 2) (1 . 2))

(counter '(d b a c b b a))
=> '((b . 3) (a . 2) (d . 1) (c . 1))

Upvotes: 2

mobyte
mobyte

Reputation: 3752

This is solution in clojure. But I hope it'll be helpful:

(defn counter [l]
  (map (fn [e]
         [e (count (filter #{e} l))])
       (distinct l)))

(counter [3 1 3 2 1 2 3 3 3])
-> ([3 5] [1 2] [2 2])

(counter '(d b a c b b a))
-> ([d 1] [b 3] [a 2] [c 1])

Upvotes: 0

Related Questions