I think you want to calculate a percentage list equal to each element. You used the word "unique", but this is a bit confusing as there are no unique elements in your list. This is based on your input and output example, where the list (1 2 1 1 2 3 3 4 4 4)consists of "30% units."
You can break it down into roughly a recursive algorithm consisting of the following steps:
- If the input list is empty, return an empty list.
- Otherwise, get the first item. Calculate how many times this happens on the list.
- Calculate the percentage and
consitem with this percentage. - Remove all occurrences of the first item from the list
cdrin the list. - Record this list and the
conslist of pairs (element . percentage).
To make the first part, use filter:
> (filter (lambda (x) (eq? (car A) x)) A)
(1 1 1)
A (1 1 1). , :
> (length (filter (lambda (x) (eq? (car A) x)) A))
3
, (length A) 100:
> (* 100 (/ (length (filter (lambda (x) (eq? (car A) x)) A)) (length A)))
30
cons (car A) .
, remove, filter: , :
> (remove (lambda (x) (eq? (car A) x)) A)
(2 2 3 3 4 4 4)
, . , ( ) . , - , , .
, , , , , . , !
(define (percentages all)
(let ((len (length all))) ; pre-calculate the length
;; this is an internal definition which is called at ***
(define (p rest)
(if (null? rest)
rest
;; equal-to is a list of all the elements equal to the first
;; ie something like (1 1 1)
(let ((equal-to (filter (lambda (x) (eq? (car rest) x))
rest))
;; not-equal-to is the rest of the list
;; ie something like (2 2 3 3 4 4 4)
(not-equal-to (remove (lambda (x) (eq? (car rest) x))
rest)))
(cons (cons (car rest) (* 100 (/ (length equal-to) len)))
;; recurse on the rest of the list
(p not-equal-to)))))
(p all))) ; ***