fork download
  1. ; sorting by frequency
  2.  
  3. (import (rnrs sorting (6)))
  4. (import (rnrs hashtables (6)))
  5.  
  6. (define (add1 x) (+ x 1))
  7.  
  8. (define (mappend f . xss) (apply append (apply map f xss)))
  9.  
  10. (define (uniq-c eql? xs)
  11. (if (null? xs) xs
  12. (let loop ((xs (cdr xs)) (prev (car xs)) (k 1) (result '()))
  13. (cond ((null? xs) (reverse (cons (cons prev k) result)))
  14. ((eql? (car xs) prev) (loop (cdr xs) prev (+ k 1) result))
  15. (else (loop (cdr xs) (car xs) 1 (cons (cons prev k) result)))))))
  16.  
  17. (define (eql? lt?)
  18. (lambda (a b)
  19. (not (or (lt? a b) (lt? b a)))))
  20.  
  21. (define (freq-lt? lt?)
  22. (lambda (a b)
  23. (or (< (cdr b) (cdr a))
  24. (and (not (< (cdr a) (cdr b)))
  25. (lt? (car a) (car b))))))
  26.  
  27. (define (sort-by-freq lt? xs)
  28. (mappend (lambda (x) (make-list (cdr x) (car x)))
  29. (list-sort (freq-lt? lt?)
  30. (uniq-c (eql? lt?)
  31. (list-sort lt? xs)))))
  32.  
  33. (display (sort-by-freq < '(2 3 5 3 7 9 5 3 7))) (newline)
  34.  
  35. (define (sort-by-freq lt? xs)
  36. (let ((ht (make-eq-hashtable)))
  37. (do ((xs xs (cdr xs))) ((null? xs))
  38. (hashtable-update! ht (car xs) add1 0))
  39. (call-with-values
  40. (lambda () (hashtable-entries ht))
  41. (lambda (keys values)
  42. (mappend (lambda (x) (make-list (cdr x) (car x)))
  43. (list-sort (freq-lt? lt?)
  44. (map cons (vector->list keys)
  45. (vector->list values))))))))
  46.  
  47. (display (sort-by-freq < '(2 3 5 3 7 9 5 3 7))) (newline)
Success #stdin #stdout 0.06s 9688KB
stdin
Standard input is empty
stdout
(3 3 3 5 5 7 7 2 9)
(3 3 3 5 5 7 7 2 9)