-2

I am trying to find frequency of the letters in a list with using scheme language but I can not do it for 4 days, and code must be work in repl.it

For example, our list is

 (a a a a b c c a a d e e e e)

our output should be

(4 a ) b ( 2 c ) ( 2 a ) d ( 4 e )

I have code which can also work on repl.it

(define (countW list1)
  (if (null? list1) 
   '()
   (let ((reserv (list 1)))        
      (let loop ((source   reserv)       
                 (elter (car list1))
                 (counter 1) 
                 (list1 (cdr list1)))
         (if (and (not (null? list1))
                  (equal? elter (car list1)))
            (loop source elter (+ counter 1) (cdr list1))
            (begin
               (set-cdr! source 
                         (list (if (= 1 counter) 
                                   elter 
                                   (list elter counter))))
               (if (null? list1)
                  (cdr reserv)     
                  (loop (cdr source) (car list1) 1 (cdr list1)))))))))

Here is the code that I try

Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • 2
    Can you show us the 4 days of your work? Tell us where you got stuck. – Mulan Dec 01 '18 at 21:35
  • this is "run-length encoding" FYI. Frequency counts would output `(( 6 a ) ( 1 b ) ( 2 c ) ( 1 d ) ( 4 e ))`. But please do edit your post to include any code of yours that you wrote. – Will Ness Dec 02 '18 at 16:28
  • what is your question? does the new code work, or is there some problem with it? was the result not as expected, or there were some error messages? please include all this relevant info. – Will Ness Dec 24 '19 at 09:21

2 Answers2

1

Fold over the list, beginning with an empty list as the accumulator. For every item, check: If the accumulator is empty, add the item (implicit count of 1). If the accumulator has a single item at the front that matches this one, replace it with a count of 2 for this item. If the accumulator has a pair at the front that matches this one, increment its count by one. Otherwise, add the item (implicit count of 1).

(define (count-occurrences lat)
  ; Get the results in the order of the input list
  (reverse
    (fold (lambda (item acc)
            (cond
              ; Start off by counting the first item
              ((null? acc)
               (cons item acc))
              ; If the previous item was this one, set its count to 2
              ((and (atom? (car acc))
                    (eqv? item (car acc)))
               (cons (list 2 item)
                     (cdr acc)))
              ; If there has been a run of this item, increment the count by 1
              ((and (pair? (car acc))
                    (eqv? item (cadar acc)))
               (cons (list (+ 1 (caar acc)) item)
                     (cdr acc)))
              ; The previous item was not this one, so start counting this one now
              (else
                (cons item acc))))
          '()
          lat)))

The fold function often requires srfi-1.

Billy Brown
  • 2,272
  • 23
  • 25
1

I have code which can also work on repl.it

(define (countW list1)
  (if (null? list1) 
   '()
   (let ((reserv (list 1)))        
      (let loop ((source   reserv)       
                 (elter (car list1))
                 (counter 1) 
                 (list1 (cdr list1)))
         (if (and (not (null? list1))
                  (equal? elter (car list1)))
            (loop source elter (+ counter 1) (cdr list1))
            (begin
               (set-cdr! source (list (if (= 1 counter) elter (list elter counter))))
               (if (null? list1)
                  (cdr reserv)     
                  (loop (cdr source) (car list1) 1 (cdr list1)))))))))